继承一个元表(类),并使用其所需的构造函数参数。
2015-1-5 6:22:13
收藏:0
阅读:115
评论:1
我发现这个教程: http://lua-users.org/wiki/InheritanceTutorial
我有一个叫做Creature的元表。Creature需要一个参数作为它的构造函数。
必需的参数是一个代表名称的字符串。
local creature = Creature(name)
- Creature有很多其他方法,如
getDescription()。 - Creature的
getDescription()返回一个字符串:“_This is a creature_”。 - Creature的
getName()返回一个字符串:名称
我想创建一个叫做Player的新元表(类),并使它继承Creature元表(类)
- Player类仅覆盖_getDescription()_方法。
- Player类还将继承Creature的getName()方法。
- Player的_getDescription()_返回一个字符串:“_This is a player_”。
我想能够执行以下操作:
local creature = Creature("Bob")
print(creature:getDescription())
print(creature:getName())
local player = Player("Joey")
print(player:getDescription())
print(player:getName())
应该打印:
这是一个生物
鲍勃
这是一名球员
琼尼
基本上,我的问题是Creature类需要一个参数来识别某人,即一个名称。它的getName()函数使用参数中的值并打印它。如果我要使用Player来继承Creature的所有函数(并在必要时覆盖),如何更改代码以确保Player获取所需的参数?
从教程中拍摄的代码:
- 从基本类创建一个新类
--
function inheritsFrom( baseClass )
--以下行与SimpleClass示例相同:
--创建表示类的表和元表。
local new_class = {}
local class_mt = { __index = new_class }
--请注意,此函数使用class_mt作为upvalue,因此类的每个实例
--将共享相同的元表。
--
function new_class:create()
local newinst = {}
setmetatable( newinst, class_mt )
return newinst
end
--以下是实现继承的关键:
--新类的元表中的__index成员引用
--基类。这意味着基类的所有方法将
--暴露给子类,并且子类可以覆盖
--其中的任何一个方法。
--
if baseClass then
setmetatable( new_class, { __index = baseClass } )
end
return new_class
end
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在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中获取用户配置主目录的跨平台方法
我想要实现以下功能:
local creature = Creature("Bob") print(creature:getDescription()) print(creature:getName()) -- ...在 Lua 中支持这种类使用语法当然是可能的 - 只是问题在于如何使用语言机制和工具来实现。需要决定的一些重要问题:
从维基教程中可以看到
new_class:create()创建了一个新实例但不会调用任何 构造 函数。因此,在您的面向对象编程系统中,您需要决定客户端代码提供的 构造函数式 函数,类创建将调用该函数。例如:function new_class:create(...) local instance = setmetatable( {}, class_mt ) if new_class.__init__ then new_class.__init__(instance, ...) end return instance end这里我只是使用
__init__作为构造函数名,类似于 Python,但实际上只要使用的代码和类创建代码一致,任何名称都可以。为了支持像
Creature("Bob"),Player("Joey")这样的对象创建语法,您可以将它们作为实际函数调用,也可以使用__call元方法。使用后者时,只需将其赋值给__call:function inheritsFrom( baseClass ) local new_class = setmetatable( {}, { __index = baseClass } ) -- ... getmetatable(new_class).__call = new_class.create return new_class end对于最后一个问题,您只需在派生类中为该方法分配一个新函数即可覆盖现有方法。例如,要在
Player中重载getDescription,可以这样做:function Player:getDescription() return "Is a player" end将所有内容放在一起,
inheritsFromfunction inheritsFrom( baseClass ) local new_class = setmetatable( {}, { __index = baseClass } ) local class_mt = { __index = new_class } function new_class:create(...) local instance = setmetatable( {}, class_mt ) if new_class.__init__ then new_class.__init__(instance, ...) end return instance end getmetatable(new_class).__call = new_class.create return new_class end定义类
Creature和一个实例:local Creature = inheritsFrom { __init__ = function(self, name) self.name = name end; getDescription = function(self) return "Is a creature" end; getName = function(self) return self.name end; } local bob = Creature "Bob" print(bob:getDescription()) print(bob:getName())从
Creature中创建一个子类Player并重载getDescription:local Player = inheritsFrom(Creature) function Player:getDescription() return "Is a player" end local joey = Player "Joey" print(joey:getDescription()) print(joey:getName())最后一句话:Lua 的 Penlight 库已经实现了类似于上述描述的 类系统,并且更加功能齐全和完整。除非这是一个练习,否则请考虑使用它来代替重新发明另一个 Lua 面向对象编程系统。