Oop Lua类继承问题
我在卢阿有两个班。一个继承另一个Oop Lua类继承问题,oop,class,inheritance,lua,multiple-inheritance,Oop,Class,Inheritance,Lua,Multiple Inheritance,我在卢阿有两个班。一个继承另一个 test1 = {test1Data = 123, id= {0,3}} function test1:hello() print 'HELLO!' end function test1:new (inp) inp = inp or {} setmetatable(inp, self) self.__index = self return inp end test2 = {} function test2:bye ()
test1 = {test1Data = 123, id= {0,3}}
function test1:hello()
print 'HELLO!'
end
function test1:new (inp)
inp = inp or {}
setmetatable(inp, self)
self.__index = self
return inp
end
test2 = {}
function test2:bye ()
print ('BYE!', self.id)
end
function test2:new_inst_test (baseClass, inp)
inp = inp or {}
setmetatable(inp, self)
self.__index = self
if baseClass then
setmetatable( inp, { __index = baseClass } )
end
return inp
end
a = test1:new({passData='abc1'})
b = test1:new({passData='ghyrty'})
c = test2:new_inst_test(a,{temp = '123343321135'})
d = test2:new_inst_test(b, {temp = '1'})
print (c.temp, c.test1Data, c.passData)
print (d.temp, d.test1Data, d.passData)
c:bye()
c:hello()
我希望test2不仅继承test1,而且保存自己的方法(“bye”)。
可能吗?
谢谢 我认为应该在类元表上设置一个_index=baseclass的元表。但这将改变test2类中所有对象的元表。这样做,您将使用来自类本身的方法,并且仅当当前类或其元表中不存在该方法时,才使用来自父级的方法 所以应该是这样
if baseClass then
setmetatable( self, { __index = baseClass } )
end
另一方面,在创建新实例时只指定基类,而不是在创建新类时指定基类,这有点奇怪。
所以我会重新思考如何在类之间继承,而不是在实例和类之间继承
作为一个以巫术为主题的小例子:
--oop.lua Example of OOP and inheritance in Lua
Person={
age=0,
className='Person'
}
-- needed if needed add comparisons, operations, ...
mtPerson={}
mtPerson.__index={
getClassName=function(self)
return self.className
end,
new=function(self,t)
return setmetatable(t or {},{__index=self})
end,
inherit=function (self,t,methods)
-- This is the heart of the inheritance: It says:
-- Look it up in the methods table, and if it's not there, look it up in the parrent class (her called self)
-- You pass this function the parent class (with :), a table of attributes and a table of methods.
local mtnew={__index=setmetatable(methods,{__index=self})}
return setmetatable(t or {},mtnew)
end,
introduce=function(self)
print(("Hi! I'm %s, I'm a %s and I'm %d years old"):format(self.instanceName,self.className,self.age))
end
}
setmetatable(Person,mtPerson)
-- Wizard inherits from the class Person, and adds some default values and methods
Wizard=Person:inherit({
className="Wizard",
knownSpells={},
},
{
listSpells=function(self)
print("known spells:",self)
if #self.knownSpells==0 then
print'none'
else
for k,v in ipairs(self.knownSpells) do
print(k,v)
end
end
end
}
)
i1=Person:new{
inventory={'wallet'},
instanceName="John",
}
i2=Wizard:new{ -- inherited method "new"
inventory={'wallet','wand','cloak of invisibility'},
instanceName="Harry",
age=20,
knownSpells={'Avada kavedra', 'Sesame open'}
}
i1:introduce() -- inherited method "introduce" notice that qge is the default value of 0
i2:introduce() --
i2:listSpells() -- method only in class 2
i1.age=26
i1:introduce() -- changed age of instance
print(Person.age) -- didn't change class defaults
print(Wizard.age)
i1:listSpells() -- Error.
在写这篇文章时,我得出结论,Lua中的OOP同时非常简单,也非常复杂。您只需在编写代码之前认真思考问题,然后再坚持计划。因此,这里我选择将属性放在类和实例表中,并将所有方法放在各自的元表中。我这样做是因为现在可以很容易地遍历所有属性,而不会遇到方法,但是任何有效的选择都是有效的。你只要选一个就行。我知道,它看起来很奇怪。我只想有可能创建一个类,这将是两个类的“和”(它将有所有的方法和变量),如果你像我说的那样实现它,它会的。方法和变量的优先级如下:首先是实例的变量和方法,然后是实例所属类中的变量和方法,然后是实例的类继承自的类中的变量和方法。您应该做的唯一一件事是在创建类时指定继承,而不是在创建实例时指定继承。这是因为每次你指定一个不同的基类,它将改变整个类,而不仅仅是你正在创建的实例。你能写一个小例子吗?)我将非常感激。因为我对Lua很陌生,我完全被这项遗产所束缚……哇!谢谢我选择了一种稍微不同的方法(从样本中采用)。但如果我再次被绊倒,我一定会以你为例!可能重复的