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
如果對象是指定類或其子類的實例,返回 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)