Lua该如何实现一个类,实现继承

 Lua是一门解释型语言,C++,C#,Java等高级语言都属于编译型语言,编译型语言同解释型语言有着很大差别。(看官请自行百度)

 Lua没有类和继承的概念,但是很多业务场景中,我们会需要自行实现类与继承的概念,以方便开发工作:Lua中table 是一个很强大的东西。

不多说无关紧要的:进入正题:

 

 1 --@param string classname 类名
 2 --@param [mixed super] 父类或者创建对象实例的函数
 3 
 4 function class(classname, super)
 5     local superType = type(super)
 6     local cls
 7 
 8     if superType ~= "function" and superType ~= "table" then
 9         superType = nil
10         super = nil
11     end
12 
13     if superType == "function" or (super and super.__ctype == 1) then
14         -- inherited from native C++ Object
15         cls = {}
16 
17         if superType == "table" then
18             -- copy fields from super
19             for k,v in pairs(super) do cls[k] = v end
20             cls.__create = super.__create
21             cls.super    = super
22         else
23             cls.__create = super
24             cls.ctor = function() end
25         end
26 
27         cls.__cname = classname
28         cls.__ctype = 1
29 
30         function cls.new(...)
31             local instance = cls.__create(...)
32             -- copy fields from class to native object
33             for k,v in pairs(cls) do instance[k] = v end
34             instance.class = cls
35             instance:ctor(...)
36             return instance
37         end
38 
39     else
40         -- inherited from Lua Object
41         if super then
42             cls = {}
43             setmetatable(cls, {__index = super})
44             cls.super = super
45         else
46             cls = {ctor = function() end}
47         end
48 
49         cls.__cname = classname
50         cls.__ctype = 2 -- lua
51         cls.__index = cls
52 
53         function cls.new(...)
54             local instance = setmetatable({}, cls)
55             instance.class = cls
56             instance:ctor(...)
57             return instance
58         end
59     end
60 
61     return cls
62 end
View Code

如果对象是指定类或其子类的实例,返回 true,否则返回 false

简单实例:

local Animal = class("Animal")
local Duck = class("Duck", Animal)

print(iskindof(Duck.new(), "Animal")) -- 输出 true

 

-- 定义名为 Shape 的基础类
local Shape = class("Shape")

-- ctor() 是类的构造函数,在调用 Shape.new() 创建 Shape 对象实例时会自动执行
function Shape:ctor(shapeName)
    self.shapeName = shapeName
    printf("Shape:ctor(%s)", self.shapeName)
end

-- 为 Shape 定义个名为 draw() 的方法
function Shape:draw()
    printf("draw %s", self.shapeName)
end

--

-- Circle 是 Shape 的继承类
local Circle = class("Circle", Shape)

function Circle:ctor()
    -- 如果继承类覆盖了 ctor() 构造函数,那么必须手动调用父类构造函数
    -- 类名.super 可以访问指定类的父类
    Circle.super.ctor(self, "circle")
    self.radius = 100
end

function Circle:setRadius(radius)
    self.radius = radius
end

-- 覆盖父类的同名方法
function Circle:draw()
    printf("draw %s, raidus = %0.2f", self.shapeName, self.raidus)
end

--

local Rectangle = class("Rectangle", Shape)

function Rectangle:ctor()
    Rectangle.super.ctor(self, "rectangle")
end

--

local circle = Circle.new()             -- 输出: Shape:ctor(circle)
circle:setRaidus(200)
circle:draw()                           -- 输出: draw circle, radius = 200.00

local rectangle = Rectangle.new()       -- 输出: Shape:ctor(rectangle)
rectangle:draw()      

 

以上创建class 概念的方法是cocos2d 中使用到的方式,也是推荐的方式,这个方式可以在Unity 中同样适用。

 

 

第二种更简单实用的方式:

在Unity 开发过程中我们很多时候会采用热更新的解决方案,当然在cocos 开发过程中也一样,作为解释型语言,lua脚本可以作为资源被打包,逻辑写在lua脚本中

Account={name='li',balance=100}

function Account:withdraw(v)
    self.balance=self.balance-v
    end
    
function Account:new(o)
    o =o or {}  --如果用户没有提供table,则创建一个
    setmetatable(o,self) --设置o的原表为Account
    self.__index=self--设置Account的索引为它自身
    return o
end

acc = Account:new()
acc:withdraw(0)
print(acc.balance)
print(acc.name)

---------------Lua模拟继承---------------------------
--子类继承父类
SpecialAccount =Account:new({limit=1000}) 
--子类重写父类的方法
function SpecialAccount:withdraw(v)
    print('SpecialAccount的方法')
    self.balance=self.balance-v
end
--实例化一个子类对象
 vip=SpecialAccount:new()
--调用从写的方法
vip:withdraw(100)
print(vip.balance)

 

posted @ 2018-04-03 10:57  Alex1991  阅读(3083)  评论(0编辑  收藏  举报