如何在Lua中实现OO?
2011-1-25 21:30:47
收藏:0
阅读:201
评论:5
Lua 没有内置的面向对象支持,但你可以自己构建。你能分享一些实现面向对象的方法吗?
每个回答请写一个示例。如果你有多个示例,请发另一个回答。
原文链接 https://stackoverflow.com/questions/4799078
点赞
stackoverflow用户30470
对于一个快速粗糙的面向对象实现,我会采用以下方法:
function newRGB(r,g,b)
return {
red=r;
green=g;
blue=b;
name='';
setName = function(self,name)
self.name=name;
end;
getName = function(self)
return self.name;
end;
tostring = function(self)
return self.name..' = {'..self.red..','..self.green..','..self.blue..'}'
end
}
end
然后可以这样使用-
blue = newRGB(0,0,255);
blue:setName('blue');
yellow = newRGB(255,255,0);
yellow:setName('yellow');
print(yellow:tostring());
print(blue:tostring());
对于更完善的方法,我将使用eemrevnivek提到的面向对象库。您还可以在此处找到一个简单的类函数,介于完整的库和快速粗糙之间。
2011-01-26 18:12:53
stackoverflow用户513763
我通常使用的方法类似于这样:
class = {} -- 将保持为空的类
mt = {} -- 默认情况下,此处将包含所有实例
mt.new = function(self,foo)
local inst={}
if type(foo) == "table" then
for k,v in pairs(foo) do
inst[k]=v
end
else
inst.foo=foo
end
return setmetatable(inst,getmetatable(class))
end
mt.print = function(self)
print("My foo is ",self.foo)
end
mt.foo= 4 --标准foo
mt.__index=mt -- 在元表中查找所有不存在的索引
setmetatable(class,mt)
i1=class:new() -- 使用默认foo
i1:print()
i2=class:new(42)
i2:print()
i3=class:new{foo=123,print=function(self) print("Fancy printing my foo:",self.foo) end}
总之,使用元表和一些聪明的思考,几乎任何事情都是可能的:当使用类时,元表是真正的魔术。
2011-01-30 20:47:43
stackoverflow用户194106
我看到的最好的解决方案就是不要在 Lua 中实现 OO,因为在那里它不是自然的,而且有些混乱,因此需要很多行;相反,使用 Luabridge 或 Luabind 在 C++ 中实现它,这种方法是自然而强大的!
一个使用 LuaBridge 的极简示例:
m.class_<MyClass>("MyClass")
.constructor<void (*) (/* parameter types */)>()
.method("method1", &MyClass::method1)
.property_rw("property2", &MyClass::getter2, &MyClass::setter2)
.property_ro("property3", &MyClass::property3)
这会转换成自然的 Lua 语法:
c=MyClass()
c.method1()
c.property2 = c.property3 * 2
do_stuff(c.property3)
此外,支持一级继承...
2011-02-03 23:05:33
stackoverflow用户312586
这个问题已经有答案了,但是不管怎样,这是我的OOP实现:middleclass(https://github.com/kikito/middleclass)。
该库提供了创建类,实例,继承,多态和(基本的)mixin的最小面板,具有可接受的性能。
示例:
local class = require 'middleclass'
local Person = class('Person')
function Person:initialize(name)
self.name = name
end
function Person:speak()
print('Hi,我是'..self.name ..'。')
end
local AgedPerson = class('AgedPerson',Person)--或者Person:subclass('AgedPerson')
AgedPerson.static.ADULT_AGE = 18--这是一个类变量
function AgedPerson:initialize(name,age)
Person.initialize(self,name)--这在self上调用父构造函数(Person.initialize)
self.age = age
end
function AgedPerson:speak()
Person.speak(self)--打印“Hi,我是xx。”
如果(self.age <AgedPerson.ADULT_AGE)then--从实例方法访问类变量
print('我未成年。')
其他
print('我是成年人。')
end
end
local p1 = AgedPerson:new('比利·小子',13)--这相当于AgedPerson('比利·小子',13)- :new部分是隐含的
local p2 = AgedPerson:new('卢克·天行者',21)
p1:speak()
p2:speak()
输出:
嗨,我是比利·小子。
我未成年。
嗨,我是卢克·天行者。
我是成年人。
2011-03-24 13:55:03
评论区的留言会收到邮件通知哦~
推荐文章
- 如何在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 模式将字符串(嵌套数组)转换为真正的数组?
我喜欢将面向对象编程(OOP)视为在容器内(对象)封装数据的同时搭配一个可以使用此数据的操作子集。当然,这只是它的简单定义。让我们假设这就是全部,然后从中构建一些东西(Lua的其中一些OO实现对读者来说也可能会很有用)。
对Lua有一定了解的人应该知道,表(table)是存储键值对的一种好方法,结合字符串使用,事情就开始变得非常有趣了:
local obj = {} -- 一个新表 obj["name"] = "John" obj["age"] = 20 -- 不过还有一个快捷方式! print("一个人:" .. obj.name .. ",年龄为 " .. obj.age)
在表中使用字符串值作为键可以通过与C语言的结构体成员或C++/Java等相似语言中的公共成员非常相似的方式进行访问。
现在的一个酷炫的魔术:让我们将它与匿名函数结合起来。
-- 假设上一个例子中的obj对象 obj.hello = function () print("你好!") end obj.goodbye = function () print("我必须走了。") end obj.hello() obj.goodbye()
很棒,对吧?现在我们有了在表中存储函数的方法,你也可以看到这类似于其他面向对象编程语言中如何使用方法。但是缺少了一些东西。如何在我们的方法定义中访问属于对象的数据?通常通过更改表中函数的签名来解决这个问题,例如:
-- 假设上一个例子中的obj对象 obj.inspect = function (self) print("一个人:" .. self.name .. ",年龄为 " .. self.age) end obj.hello = function (self) print(self.name .. ": 你好!我是" .. self.name) end obj.goodbye = function (self) print(self.name .. ": 我必须走了。") end -- 现在,它将用对象作为第一个参数来调用 obj.inspect(obj) -- 一个人:John,年龄为 20 obj.hello(obj) -- John: 你好!我是John obj.goodbye(obj) -- John: 我必须走了。
这就是一个简单的解决方法。也许将其与Python中的工作方式进行类比(方法总是获得显式的self)可以帮助你学习如何在Lua中实现。但是,明确在方法调用中传递所有这些对象并不方便,是吧?是的,这也让我感到不安,因此为使用面向对象编程提供了另一个快捷方式:
obj:hello() -- 相当于 obj.hello(obj)
最后,我仅仅是涉及了如何实现这样的部分。正如凯文·弗默(Kevin Vermeer)的评论中所指出的那样,Lua用户维基是有关此主题的绝佳信息来源,您可以在那里了解有关此答案所忽略的其他重要面向对象编程方面的所有信息(私有成员,如何构造对象,继承等)。请记住,实现的这种方式是Lua哲学的一小部分,提供简单的正交工具,能够构建更高级的构造。