Lua 中的子 class 构造函数方法
Child class constructor method in Lua
在 Lua 中理解继承(和元表)的概念有点困难。官方教程没有具体说明如何为子class.
构造构造函数
我的例子的问题是 player:move()
是 nil
,所以玩家仍然是 Object
class
-- Generic class
Object = {}
function Object:new (type,id,name)
o = {}
self.type = type or "none"
self.id = id or 0
self.name = name or "noname"
setmetatable(o, self)
self.__index = self
return o
end
function Object:place(x,y)
self.x = x
self.y = y
end
-- Player class
Player = Object:new()
function Player:new(id,name)
o = Object:new("player",id,name)
o.inventory = {}
o.collisions = {}
return o
end
function Player:move(x,y)
return print("moved to " ..x.." x " .. y)
end
local player = Player:new(1, "plyr1")
player:move(2,2)
在构造函数 Player:new
中,我们通过以下行返回 Object
class 的对象:
o = Object:new("player",id,name)
一旦我们删除它,player:move()
将被调用:
moved to 2 x 2
原因是,即使我们正在调用 Player:new
构造函数,我们实际上在其中返回了 Object
class 的一个实例。在这种情况下,o
继承了 属性。
classes 继承示例
通用 class
Object = {}
function Object:__tostring()
if rawget(self, "type") then -- only classes have field "type"
return "Class: "..tostring(self.type)
else -- instances of classes do not have field "type"
return
"Type: "..tostring(self.type)..", id: "..tostring(self.id)
..", name: "..tostring(self.name)
end
end
function Object:newChildClass(type) -- constructor of subclass
self.__index = self
return
setmetatable({
type = type or "none",
parentClass = self,
__tostring = self.__tostring
}, self)
end
function Object:new(id, name) -- constructor of instance
self.__index = self
return
setmetatable({
id = id or 0,
name = name or "noname"
}, self)
end
function Object:place(x,y)
self.x = x
self.y = y
end
玩家class
Player = Object:newChildClass("player")
function Player:new(id,name)
local o = Player.parentClass.new(self, id, name) -- call inherited constructor
o.inventory = {}
o.collisions = {}
return o
end
function Player:move(x, y)
self:place(x, y)
print("moved to (" ..self.x..", " .. self.y..")")
end
local player = Player:new(1, "plyr1")
print(player) --> Type: player, id: 1, name: plyr1
player:move(2,2) --> moved to (2, 2)
如何创建子class并调用继承的方法
Dog = Player:newChildClass("dog")
--- we want to override method "move" in class "dog"
function Dog:move(x, y)
Dog.parentClass.move(self, x, y) -- call inherited method "move"
print("Woof!") -- dog says "woof" after every move
end
local dog = Dog:new(42, "dg42")
print(dog) --> Type: dog, id: 42, name: dg42
dog:move(3,4) --> moved to (3, 4)
--> Woof!
在 Lua 中理解继承(和元表)的概念有点困难。官方教程没有具体说明如何为子class.
构造构造函数我的例子的问题是 player:move()
是 nil
,所以玩家仍然是 Object
class
-- Generic class
Object = {}
function Object:new (type,id,name)
o = {}
self.type = type or "none"
self.id = id or 0
self.name = name or "noname"
setmetatable(o, self)
self.__index = self
return o
end
function Object:place(x,y)
self.x = x
self.y = y
end
-- Player class
Player = Object:new()
function Player:new(id,name)
o = Object:new("player",id,name)
o.inventory = {}
o.collisions = {}
return o
end
function Player:move(x,y)
return print("moved to " ..x.." x " .. y)
end
local player = Player:new(1, "plyr1")
player:move(2,2)
在构造函数 Player:new
中,我们通过以下行返回 Object
class 的对象:
o = Object:new("player",id,name)
一旦我们删除它,player:move()
将被调用:
moved to 2 x 2
原因是,即使我们正在调用 Player:new
构造函数,我们实际上在其中返回了 Object
class 的一个实例。在这种情况下,o
继承了 属性。
classes 继承示例
通用 class
Object = {}
function Object:__tostring()
if rawget(self, "type") then -- only classes have field "type"
return "Class: "..tostring(self.type)
else -- instances of classes do not have field "type"
return
"Type: "..tostring(self.type)..", id: "..tostring(self.id)
..", name: "..tostring(self.name)
end
end
function Object:newChildClass(type) -- constructor of subclass
self.__index = self
return
setmetatable({
type = type or "none",
parentClass = self,
__tostring = self.__tostring
}, self)
end
function Object:new(id, name) -- constructor of instance
self.__index = self
return
setmetatable({
id = id or 0,
name = name or "noname"
}, self)
end
function Object:place(x,y)
self.x = x
self.y = y
end
玩家class
Player = Object:newChildClass("player")
function Player:new(id,name)
local o = Player.parentClass.new(self, id, name) -- call inherited constructor
o.inventory = {}
o.collisions = {}
return o
end
function Player:move(x, y)
self:place(x, y)
print("moved to (" ..self.x..", " .. self.y..")")
end
local player = Player:new(1, "plyr1")
print(player) --> Type: player, id: 1, name: plyr1
player:move(2,2) --> moved to (2, 2)
如何创建子class并调用继承的方法
Dog = Player:newChildClass("dog")
--- we want to override method "move" in class "dog"
function Dog:move(x, y)
Dog.parentClass.move(self, x, y) -- call inherited method "move"
print("Woof!") -- dog says "woof" after every move
end
local dog = Dog:new(42, "dg42")
print(dog) --> Type: dog, id: 42, name: dg42
dog:move(3,4) --> moved to (3, 4)
--> Woof!