It looks like you're new here. If you want to get involved, click one of these buttons!
Base = Core.class() function Base:init() self:say('balabala') end function Base:hello() print('hello from base') end function Base:say(what) print('say from Base', what) end Child = Core.class(Base) function Child:init() --self:say('balabala') end function Child:hello() print('hello from Child') end function Child:say(what) print('say from Child', what) end local child = Child.new() child:hello() |
Likes: Yan
Comments
I tried it in C++, Base Class always call it's own method in construct.
May be I must move all of my overwritable functions out of the init call.
)
https://sites.google.com/site/xraystudiogame
http://stackoverflow.com/questions/36832/virtual-functions-in-constructors-why-do-languages-differ
All I can say is that in Smalltalk (which in my opinion is the original and "correct" OO language) it *is* possible to call overridden functions in an initialize (constructor) method. The problem with the current way of working is that it often makes it difficult to specialise the way an object is created without having to create an intermediate abstract base class or a "wrapper" factory method.
This is specifically important when adding event listeners. Let's say that I have a base class with an ENTER_FRAME listener and I want to override this in a subclass with another different ENTER_FRAME listener.
If I wanted the original base listener functionality I would expect to call the super class method like this:
best regards
Currently, if Base class is registering an ENTER_FRAME event (even through another function), you cannot change/alter/override it with a Derived class.
Let me play with Middleclass some more. I know you're a master of Smalltalk and thank you for great information.
One thing you could add, though, is an init2() function (please choose a better name) that is automatically called by the framework on an object after it has been created. That way, people who want to use the functionality described above can ignore init() and just implement init2() or they can use use a combination of both.
One of the things that makes the Gideros class system generally easier to use is the fact that the superclass constructor is automatically called for you. However, this can also be inflexible since, sometimes, you'd really like to be able to choose when it is called. You could use the init2() idea to implement a more traditional constructor scheme where one has to explicitly decide when/if to call the super constructor (i.e. when using init2() the super ctor is not called automatically).
So implementing init2() would allow us to have the best of both worlds and wouldn't break any existing code.
BTW, if you are going to add this (and it would get much =D> from me) then you might also like to think about adding the superclass as a field of all objects. That way, we'd be able to call superclass methods easily like this:
Likes: alexzheng
And about calling superclass function you can simply do:
So how about "created" as a method name?
But postInit also sounds nice
In fact, we need to choose a bit unusual name because if someone has already created a function with the same name, it'll be called twice (in that case, we shouldn't give a name as "created" )
@atilim, can you add that .super assignment to Core.class() so it is performed automatically?
best regards
Likes: bowerandy
Before you commit this here are some more additions that you might like to consider. They add an optional classname as a second parameter to Core.class and also a "class" field to be able to know the exact class of any instance. This allows you to easily add an isKindOf() function:
https://github.com/kikito/middleclass/blob/master/middleclass.lua
BTW, I forgot to thank you for adding these changes.
best regards
Likes: OZApps
And I can add isInstanceOf also. Do you think this is a good function name for this purpose. (I couldn't explain the difference between isKindOf and isInstanceOf but you can already guess )
With regard to isInstanceOf() I would be tempted to just add a getClass() method that returns the class object so the programmer can write:
best regards
Now As a workaround I move all the overwritable initializtion into ADD_TO_STAGE event listener. It seems the ENTER_FRAME event listener can aslo be overided.
https://sites.google.com/site/xraystudiogame
Make a little complicated code to test it.
It still have some bug.
https://sites.google.com/site/xraystudiogame
self.super.postInit(self)
this works the same as Base.someFunction(self)
https://sites.google.com/site/xraystudiogame
Why not call it onInit or onCreate, that sounds more like an auto called callback.
https://sites.google.com/site/xraystudiogame
onInit and onCreate are also good names. But I think I'll stick with postInit.
@hgvyas123 it's only an extra functionality. The class system is going to work as before.
@bowerandy if it's ok for you, let me add __tostring, isKindOf and naming of the classes to the future versions. Currently, I cannot decide how to implement them properly. Here, I think postInit was the important one and the others are a little bit optional.
Likes: hgvyas123
can you clarify this state:
Currently, if Base class is registering an ENTER_FRAME event (even through another function), you cannot change/alter/override it with a Derived class.
But,if the ENTER_FRAME event is registered outside of the init,it can be overridden.
https://sites.google.com/site/xraystudiogame
https://sites.google.com/site/xraystudiogame
With the new modifications, my recommendation would be to forget that init() exists at all. If you just use postInit() instead you should find the code behaves as you requested at the head of this thread.
Base:postInit table: 0x8019138
Base:setupListener table: 0x8019138
Derived:postInit table: 0x8019138
Base:onAddtoStage table: 0x8019138
Derived:onTouchBegin table: 0x8019138
Derived:onTouchBegin table: 0x8019138
Notice how self is now the same object throughout.
best regards
Likes: vitalitymobile
@atilim, sure, include what you feel happiest with. I do think including the optional classname parameter might be a good idea though. It can make debugging quite a bit easier and I can't see how it would break anything. I agree that __tostring would change quite a bit and would probably be a bad idea. isKindOf() and isInstanceOf() are nice ideas but not really essential (and testing on type is generally considered bad practice anyway).
Actually, here's an idea. If you included a "god object" class as the root of all classes, the developer could add any of these features him/herself. I don't think this would cause any efficiency issues either.
best regards
Likes: alexzheng