Lua类继承问题。
2011-8-3 13:40:23
收藏:0
阅读:119
评论:1
我在 Lua 中有两个类。一个继承另一个。
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')。这是可能的吗? 谢谢!
原文链接 https://stackoverflow.com/questions/6927364
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
我认为你应该在类元表中设置一个带有 __index=baseclass 的元表。但这将改变测试2类中所有对象的元表。通过这种方式,你将使用类本身的方法,并且仅在当前类中不存在该方法或其元表时才使用父类的方法。
所以应该像这样:
if baseClass then setmetatable( self, { __index = baseClass } ) end
另一方面,仅在创建新实例时指定 baseclass 而不是在创建新类时指定,有点奇怪。因此,我会重新思考如何在类之间继承,而不是在实例和类之间继承。
下面是一个小的巫师主题示例:
--oop.lua Lua 中面向对象编程和继承的示例 Person={ age=0, className='Person' } -- 需要使用,如果需要添加比较、操作等... 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) -- 这是继承的核心:它说: -- 在 methods 表中查找它,如果它不在,就在父类中 (这里称为 self) 查找。 -- 你需要通过 : 将此函数传递给父类(一个表的形式),一些属性表和方法表。 local mtnew={__index=setmetatable(methods,{__index=self})} return setmetatable(t or {},mtnew) end, introduce=function(self) print(("嗨!我是%s, 我是一个%s,今年%d岁"):format(self.instanceName,self.className,self.age)) end } setmetatable(Person,mtPerson) -- Wizard 从类 Person 继承,并添加一些默认值和方法 Wizard=Person:inherit({ className="Wizard", knownSpells={}, }, { listSpells=function(self) print("已知咒语:",self) if #self.knownSpells==0 then print'无' 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{ -- 继承的方法 "new" inventory={'wallet','wand','cloak of invisibility'}, instanceName="Harry", age=20, knownSpells={'Avada kavedra', 'Sesame open'} } i1:introduce() -- 继承的方法 "introduce",请注意年龄是默认值 0 i2:introduce() -- i2:listSpells() -- 仅在类 2 中的方法 i1.age=26 i1:introduce() -- 实例年龄更改 print(Person.age) -- 未更改类的默认值 print(Wizard.age) i1:listSpells() -- 错误。
在编写此代码时,我得出的结论是 Lua 中的面向对象编程既非常简单,又非常复杂。在编写代码之前,你必须仔细考虑,然后在计划之后坚持。因此,在这里,我选择将属性放在类和实例表中,并将所有方法放在各自的元表中。我这样做是因为现在可以轻松地遍历所有属性,而不会遇到方法,但任何有效的选择都可以。你只需要选择一种。