Object inheritance
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
- zorg
- Party member
- Posts: 3465
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: Object inheritance
Yeah, i usually prefer to completely separate classes and instances (whether with or without any kind of inheritance is in play), to me it feels more clean, and i don't need to think about mixing both behaviours into one table, but ultimately, it's just a matter of preference.
Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Re: Object inheritance
Oh I think I finally understand. Here is a clearer view of the code:
It does work but it's just not very clear IMO.
My issue is with the merging of metatables and interfaces or "classes" into a single table.
This results in weird stuff like "self.__index = self" which is executed everytime you call "new".
In theory this line doesn't need to be executed every time you create an "instance".
I'm not crazy with modifying the metatable/interface after an object is created.
It could lead to weird bugs like:
Code: Select all
A = {}
function A:new()
local o = {}
setmetatable(o, self)
self.__index = self
return o
end
function A:foo()
print('A')
end
B = A:new()
function B:foo()
print('B')
end
C = B:new()
function C:foo()
print('C')
end
a = A:new()
b = B:new()
c = C:new()
a:foo()
b:foo()
c:foo()
My issue is with the merging of metatables and interfaces or "classes" into a single table.
This results in weird stuff like "self.__index = self" which is executed everytime you call "new".
In theory this line doesn't need to be executed every time you create an "instance".
I'm not crazy with modifying the metatable/interface after an object is created.
It could lead to weird bugs like:
Code: Select all
function A:new()
local o = {}
setmetatable(o, self)
self.__index = self
o:baz() -- won't work until B:baz() is defined
return o
end
B = A:new()
function B:baz()
print('B')
end
Re: Object inheritance
Yes that's true about self.__index, you could set A.__index = A, and then do the same whenever you define a new class, or if you prefer to keep the metatable and the superclass separate you could define local metaA = {__index=A} and set that to be the metatable of subclasses. It's an additional thing to remember to do, and a little bit of code duplication, while the efficiency savings very small unless you spawn multiple instances per frame. I suppose you could define a function to initialize a table, set its index to the superclass you want, and define its __index attribute (or the separate metatable). I might give that a try next time.
That's a good point, if you want something in initialization to depend on something implemented by the subclass you can't do it cleanly like this. The webpage I initially got this from actually did this:
I didn't see why you may want to provide o at first, but now I can see why it might be helpful, you can do:
so that you can do
hmm... though now I write it out I don't like the look of it. I'll play around with that more if I run into a situation where I want some part of initialization to depend on a method of the subclass.
edit:
looks alright to me
That's a good point, if you want something in initialization to depend on something implemented by the subclass you can't do it cleanly like this. The webpage I initially got this from actually did this:
Code: Select all
function A:new(o)
local o = o or {}
setmetatable(o, self)
self.__index = self
-- more code e.g
o:baz()
return o
end
so that you can do
Code: Select all
B = {}
function B:baz()
print('B')
end
A:new(B)
edit:
Code: Select all
B = A:new({
baz=function(self)
...
end})
Re: Object inheritance
The most confusing part is that you're doing multiple things through the :new() function.
I would split that into two functions: :new() and :inherit() then the code would look much more clear.
I would split that into two functions: :new() and :inherit() then the code would look much more clear.
Re: Object inheritance
That's a pretty good idea
Re: Object inheritance
That's indeed the approach that 4vZEROv posted in the previous page (except 'inherit()' is called 'extend()' in 4vZEROv's version).
Re: Object inheritance
In my class implementation, inheritance workflow is set up like this:
Internally, it copies over all data from base class into derived class. Not having to do multiple __index hops to find inherited functions and values makes it run a lot faster, and the memory footprint increase is microscopic (it's only the class definition, not individual instances). However, this also means that it won't pick up changes made to the base class after the inheritance call, so one should only inherit from complete classes.
Code: Select all
local baseclass = Class ( "baseClassName" )
function baseclass:foo ( ) ...
local derivedclass = baseclass:extend ( "derivedClassName" )
function derivedclass:bar ( ) ...
Who is online
Users browsing this forum: Ahrefs [Bot], Google [Bot] and 5 guests