local pos1 = Position.new(1,1) print(pos1:getLength())
local pos2 = Position.new(3,4) print(pos2:getLength())
对的,下面的两种写法是等价的:
1 2
pos1.getLength(pos1) pos1:getLength()
类似的,在Position.lua中也能这么写:
1 2 3 4 5 6 7 8 9 10 11 12 13
local Position = {}
functionPosition.new(x,y) local instance = {x=x, y=y} setmetatable(instance, {__index=Position}) return instance end
functionPosition:getLength() return (self.x^2+self.y^2)^0.5 end
return Position
下面两种写法也是等价的:
1 2 3 4 5 6 7
functionPosition.getLength(self) return (self.x^2+self.y^2)^0.5 end
functionPosition:getLength() return (self.x^2+self.y^2)^0.5 end
这里的self就相当于c++的this
我们还可以把new方法抽象出来,作为公共方法,而不用为每个类都写一个new方法:
1 2 3 4 5 6 7 8 9 10 11 12 13
-- function.lua
functionclass(className) local cls = {} cls.__cname = className cls.new = function(...) local instance = {} setmetatable(instance, {__index=cls}) if cls.ctor then cls:ctor(...) end return instance end return cls end
if super then cls.super = super setmetatable(cls, {__index=super}) end cls.__cname = className
cls.new = function(...) local instance = {} setmetatable(instance, {__index=cls}) if cls.ctor then cls:ctor(...) end return instance end return cls end
这里我们将父类保存到子类的元表的__index字段中,同时为类添加了super字段用于保存父类
于是基于new方法,我们可以定义Position的子类Position3D:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
-- Position3D.lua
local Position3D = class("Position3D", require("Position"))
functionPosition3D:ctor(x,y,z) self.super:ctor(x, y) self.z = z end
functionPosition3D:getLength() return (self.x^2+self.y^2+self.z^2)^0.5 end
functionclass(className, ...) local cls = {__cname = className}
local supers = {...} for i,super inipairs(supers) do cls.__supers = cls.__supers or {} table.insert(cls.__supers, super)
if cls.super==nilthen cls.super=super end end
if cls.__supers==nilor #cls.__supers==1then setmetatable(cls, {__index=cls.super}) else local index = function(t,k) for i,v inipairs(cls.__supers) do if v[k] thenreturn v[k] end end end setmetatable(cls, {__index=index}) end
cls.new = function(...) local instance = {} setmetatable(instance, {__index=cls}) if cls.ctor then cls:ctor(...) end return instance end
return cls end
之后我们就能这样去使用多继承机制了:
1 2 3 4 5 6 7 8 9 10 11 12
--ClassA.lua
local ClassA = class("ClassA")
functionClassA:ctor() end
functionClassA:methodA() print("ClassA:methodA") end
return ClassA
1 2 3 4 5 6 7 8 9 10 11 12
--ClassB.lua
local ClassB = class("ClassB")
functionClassB:ctor() end
functionClassB:methodB() print("ClassB:methodB") end
return ClassB
1 2 3 4 5 6 7 8
--ClassC.lua
local ClassC = class("ClassC", require("ClassA"), require("ClassB"))
functionClassC:ctor() end
return ClassC
1 2 3 4 5 6 7
--main.lua
require("function")
local c = require("ClassC").new() c:methodA() c:methodB()