Overriding Create()

BlitzMax Forums/BlitzMax Beginners Area/Overriding Create()

H&K(Posted 2006) [#1]
What I want to do is extend one of the Types I have finished. (Ie, I dont want to change the base Type at all: AND, I want to pretend that I dont know how the base class works)

Arbitary example



So I get a "Super can only be used in Methods" Error.



Which, yet again gives the same error

So the specific question is How do I use super in this case.

EDITED


You can tho override a create Method. So what Ive spent all day doing is changing this
MyType:AType = AType.create()

Type AType
Function MyType:AType()
local Temp:Atype = new Atype
..
..
return temp
end function
EndType

to
MYType:AType    = New AType.Create()

Type AType
Method Create:AType ()
..
..
return Self
End Method
End Type


END EDIT



Dreamora(Posted 2006) [#2]
You can't overload functions, so you don't use it at all.

Beside that, you would do it through super.create(), as super is a reference to the base type from which this one was extended, as described in the help files.

Methods can be overloaded but their type stuff must stay as it is. You can't change return types etc.


H&K(Posted 2006) [#3]
1) I have not overloaded a function, I have Overrided it. (BIG difference)

2) Thank you very much for telling me it doesnt work, Cos I didnt know that <---- This is ment to be funny

3) Ok re phrase the question. What part of ExtededClass do I allocate BaseClass.Create to?


Dreamora(Posted 2006) [#4]
???
You do not allocate anything to anything.

You call it.

like

result:blabla = super.create()
' do additional initialisation stuff

return result


H&K(Posted 2006) [#5]
No, my create returns the new object (If you look), so the returned object (Type BaseClass) needs to be allocated to some part of extended class

Now i would have thought that
MyExtenedclassObject.Super would be the Whole base class, but it isnt.


Dreamora(Posted 2006) [#6]
as mentioned:

function create:basetype()
local result:extendedType
result = super.create()
result.somefield = someInitialisation
...
return result
end function


H&K(Posted 2006) [#7]
Again veryNice,

BUT this IS the problem.

The line Result = Super.Create() Still wouldnt work

Super.Create returns a "BASE" object, but Result expects an extened odject.

AND SO IT DOESNT WORK

SO AGAIN,

What part of ExtededClass do I allocate BaseClass.Create to?

Result.Super ?


Dreamora(Posted 2006) [#8]
Heard of type casting?

result = extendedType(super.create())


H&K(Posted 2006) [#9]
no.


Dreamora(Posted 2006) [#10]
then you heard it now ... :-)

But as mentioned: even then it won't work.
Overriding does not allow to change the function / method header, because BM is, as mentioned, not capable of overloading, which would be needed for that.


H&K(Posted 2006) [#11]
Ok, Just coping your code line. Solution,

Type BaseClass

Field FOne:Int

Function Create:BaseClass ()
	Local 	Temp:BaseClass 	= New BaseClass
		Temp.FOne		= 1
	Return Temp
End Function

EndType
'----------------------------------------------
Type ExtendClass	Extends BaseClass
	
	Field FTwo:Int
	
	Function Create:ExtendClass ()
		Local	Temp:ExtendClass	= New ExtendClass
			Temp		=ExtendClass( BaseClass.Create ()) '	<-------------- Line in question
			Temp.FTwo		= 2
			Return Temp
	End Function
End Type



Instead of trying to access the part of the extend class to allolcate the new base class to.
I needed to "Cast" then base class result into an exend class.


H&K(Posted 2006) [#12]
Damb


FlameDuck(Posted 2006) [#13]
This line:
Local	Temp:ExtendClass	= New ExtendClass
is superfluous. Just go:
Local	Temp:ExtendClass	= ExtendClass( BaseClass.Create ())



H&K(Posted 2006) [#14]
Oh well, just have to convert all my create functions to methods :(


For anyone interested this works




Grey Alien(Posted 2006) [#15]
If I need to override a method/function and give it different parameters, I end up calling it SpecialCreate or SpecialDraw etc. It's probably bad OOP design ;-)


Brucey(Posted 2006) [#16]
Except that you *cant* do the following :
is superfluous. Just go:

Local Temp:ExtendClass = ExtendClass( BaseClass.Create ())


Temp will be null.
Why? Because you can't cast in that direction.

What the line above is basically saying is "give me an ExtendClass from a BaseClass and somehow magically create the extra memory that the ExtendClass will need for all its fields etc." - which Max doesn't do.

You can cast in the *opposite* direction, eg :

Local	Temp:BaseClass	= BaseClass( ExtendClass.Create ())

because an ExtendClass is already a BaseClass.

In the above code where "FOne = 1", and if you always intend setting the value to this when the object is created, why not have :
Field FOne:Int = 1

Or, you want another method to hold initialisation stuff, you can make a "New()" method like so :
Type BaseClass

	Field FOne:Int

	Method New()
		FOne = 1
	End Method

EndType

Since New() is called *for you* whenever an object is created, it's very useful.

Here's a small example to show you how you can set fields in different places in the code.

Notice how the New() of the baseclass is called, even when you are creating the extendclass object. This is because max needs to internally create all parent parts of a type when you create a subtype.
You can also see this when you are debugging. If you look at a variable that is a subtype of another type you will see the details split into sections. A bit for each type that the object represents.

Once you get the hang of OO with Max, it's really very cool :-)

Hope this helps a bit.


FlameDuck(Posted 2006) [#17]
Except that you *cant* do the following :
I wasn't suggestiong that he could, I was suggesting that creating a New object, and then immediately replacing it with another one on the next line, made the previous line superfluous.


Brucey(Posted 2006) [#18]
True.... but it's probably harder to learn something if they are presented with code that doesn't work ;-)

And it makes for less threads like
"... but you said to do such and such..."
"... yes, but I didn't mean it like that, because you shouldn't have taken the code that I posted literally..." etc.

Anyhoo... I wasn't suggesting that you were suggesting he should code badly.... just trying to be helpful, for a change ;-)


sswift(Posted 2006) [#19]
H7K:
You have my sympathies. I just gave up on using Extend when I found out I couldn't override a Create() function with a new one with different parameters, and now you seem to have discovered it's worse than I thought and you can't override it PERIOD.

I have a fruit type which I wanted to extend a sprite type in my own code and I decided it was just easier to make a sprite field in the fruit type and create a sprite for it when I create a fruit. Then I free the sprite when I free the fruit. (I have to call a free method because both are in their own linked lists of sprites and fruits.)

This did make it a bit annoying to access the sprite's methods, as I had to go Fruitname.Spritename.X#() to get the X position of the fruit for example. (I could have made wrapper functions for all the sprite functions if I wanted to but that's a bit crazy.) But it was worth it to avoid all these oop releated headaches from tryint o use extends when there's clearly functionality missing that's needed to make it useful.


H&K(Posted 2006) [#20]
@Swift.

You can tho override a create Method. So what Ive spent all day doing is changing this
MyType:AType = AType.create()

Type AType
Function MyType:AType()
local Temp:Atype = new Atype
..
..
return temp
end function
EndType

to
MYType:AType    = New AType.Create()

Type AType
Method Create:AType ()
..
..
return Self
End Method
End Type

Then I can override the Create Method.


Grey Alien(Posted 2006) [#21]
oh that's interesting. You can't override a create function but you can if it's a method ... how strange.


H&K(Posted 2006) [#22]
Dont you go winding me up ;)

You can override a create function, but you have no way to cast the parent object down to the child object.
Its not a problem about overriding (Which you can do to both)


Grey Alien(Posted 2006) [#23]
Oh ok, that's fine then. I know about casting one way and not the other. Basically you can override functions/methods if they have the same parameters, but otherwise not. In C++ you "overload" but you can't do that in BMax.


H&K(Posted 2006) [#24]
Yep, but I didnt know about the casting one way thing until a long post thread today.

Thing is there should be a copy cast or somthing.

BUT

I dont see why there is no way to allocate a base object to the base bits of an extended object (Not create a new extened object, but just copy over the bit that are from a base object anyway.

I understand the "An extended object is a base object, but a base object is not an extended object"

But surly a base object is a bit of an extended object.


Grey Alien(Posted 2006) [#25]
just write a Copy method to do it, that's what everyone else has to do ;-)


H&K(Posted 2006) [#26]
I knew making a copy method was a solution, thats why I said I wanted to pretend the base class was uneditable, to find other solutions.


Grey Alien(Posted 2006) [#27]
I know you knew, I'm just saying that's all you can do...


H&K(Posted 2006) [#28]
Annoying isnt it


sswift(Posted 2006) [#29]
H7K:
That method thing you did there is pretty clever, but I'm not happy about it being neccessary to do that! If I tried to use that method with my sprite system it would confuse the hell out of people.


Grey Alien(Posted 2006) [#30]
wait I'm confused already. don't you need to put Self = New AType in the method before returning it?


sswift(Posted 2006) [#31]
Grey:
No. You cannot call a method without having a type instance to call it with. If you look at his code he did this:

MYType:AType = New AType.Create()

"New AType" is executed first, and creates a type. Then ".Create()" acts on that new type.

It's the same as this:
MYType:AType = New AType
MYType.Create()

Which come to think of it, might be a better way to do it since it's easier to parse. And instead of calling the method create, you could call it Init().


Grey Alien(Posted 2006) [#32]
OK I get it, but it's toally unclear for someone who will buy one of our modules.

I prefer

MyType:AType = Atype.Create(params)

And Create is a function inside the AType declaration that returns an AType. Create also often initilises at the same time, hense the params I pass in. But this is also why if you extend AType to BType you can't override function Create with different parameters...


sswift(Posted 2006) [#33]
"But this is also why if you extend AType to BType you can't override function Create with different parameters..."

But what is why? I don't see anything that would preclude that.

If BType is an extension of AType, then there's no reason both of these couldn't work:


MyType:AType = Atype.Create(param1#, Param2)
MyType:BType = Btype.Create(param1:Blah)


Grey Alien(Posted 2006) [#34]
well, like I said you could do that in C++, but really in BMax they are keeping it simple so that it works properly with polymorphism. You can call Create(sameparams) not knowing if it's AType or BType and it will work. Uh, well that works for methods, but for functions it doesn't make sense as you Have to put the type (not the instance) before the call i.e. AType.Create() so polymorphism doesn't apply there... hmm. Well I haven't actually tested that you can't override a function with one of the same name but different params. I know that you can't with methods for sure.


Dreamora(Posted 2006) [#35]
Overloading isn't in BM, so it doesn't work with functions either.
It isn't a that clean OO implementation anyway, only C language "bloodline" supports it from what I know and most likely, C# only does it because too many are used to C++ way of doing it ...

Doing it through:

.CreateFromInt(someInt,someInt)
.CreateFromVector(2DIntVector[])
.CreateFromString(someString)

is the far cleaner way and the create function declaration is more intuitive and descriptive as well (instead of several creates that await different information)


H&K(Posted 2006) [#36]
Can everyone Please please please Learn the difference between Override, and overload.

@Grey When you "Override a function with .. different params" That is overloading

(edit) @Dream. Took this out cos it looked silly as you have just posted

I spent yesturday trying to find out how to do that function create thing in the first post (Answer: Use a create Method, and it all works), This was getting me more and more frustrated. And anyone who followed the Casting thread later, will see this was asabated by be useing realese builds all day. (Im blameing ZIGGY for that ;)

What didnot help was

1) People Telling me I couldnt do somthing that I hadnt done, and saying thats why it didnt work
2) Me knowing that because Id written it, it must be right, and Blitz wrong.
3)People saying you need to use this, "######", then posting later that it still wouldnt work (you know who you are)

OverRide: When you have a Function/Method with the same "FootPrint" as one earler in the class tree.
Type AType
..
Method:Int Draw ()
Return True
End Method

Type BType Extends AType
..
Method:Int Draw ()
Return True
End Method


As we can see The first Type (AType) has a method Draw, which takes no parameters, and returns an INT. We then in the extended Type (BType) also have a method Draw, which agian takes no parameters and returns INT. In FACT it MUST, take no parameters and return INT, because it needs to look just like origional method to the comiler.

"An overloaded declaration is a declaration that had been declared with the same name as a previously declared declaration in the same scope, except that both declarations have different types.
If you call an overloaded function name or operator, the compiler determines the most appropriate definition to use by comparing the argument types you used to call the function or operator with the parameter types specified in the definitions" <---- Just Got this From the Internet.

'THIS DOES NOT WORK
Type AType
..
Method Draw:INT ()
Return TRUE
END Method
Method Draw:Float ()
Return  True
End Method


As we can see a new method Draw:float has been added to the type. These are obviously two different Methods, because look one returns an INT, the Other a FLOAT. The DRAW method is now Overloaded, There are two draws with different footprints.
These are considered different in some compilers, (Ie ones that Overload), but not in BMAx


H&K(Posted 2006) [#37]
.CreateFromInt(someInt,someInt)
.CreateFromVector(2DIntVector[])
.CreateFromString(someString)

or

.Create(someInt,someInt)
.Create(2DIntVector[])
.Create(someString)

Name(Int,Int) is different enough to Name(INT[])
The first way is not cleaner. Its just the way we are forced to do it because we cannot overload

BUT, Ive always felt that overloading was somthing just to make life easyer for the user of the class rather than the writter. And Im quite willing to live without :)


Grey Alien(Posted 2006) [#38]
@Grey When you "Override a function with .. different params" That is overloading
I know that, thanks ;-) I've been doing OOP for 10 years in Delphi and C++. It's just that BMax is a limited subset of C++'s OOP (for simplicity) and we all have to get used to what it does and doesn't do. It does overriding, but not overloading, simple really (affects methods AND functions, I tested both).


H&K(Posted 2006) [#39]
I Knew you Knew, and I Know Dream knows as well. The problem is that we (Ie the People that Know), tend to use them interchangeably.
This is not a problem for us. Because we know what we mean, and are have used compilers where it didnt matter cos they did them both.
The problem will be for new or novice programers, who will probably get confused, because we dont use the tearms proply. I was not posting the definition to tell you what they ment. I was posting the definition in the hope that from now on we can be concistent in posts which, if you read back over this thread, we have not been.
After all it does make a difference in Bmax, Because it can be overridden, but not overloaded.


Grey Alien(Posted 2006) [#40]
yes that's true, consistency is good.