Lua中面向對象編程的理解

模塊


模塊是一個獨立的空間,一個獨立的環境,訪問模塊成員須要先require,並使用「模塊名.成員名稱」的格式訪問。注意:模塊是一個table。


在lua中全部對象都是一個table,類也是一個table,但類應該是一個只讀的table,類的定義是經過建立一個模塊實現的。

lua代碼:
module("Student",package.seeall)

function study(self)

end


在調用module方法時添加package.seeall參數的做用是:讓該模塊能夠訪問全局變量。

對象


對象是一個類的實例,在Lua中對象是一個table,在Lua中類更像是一個原型(一個只讀的對象)。

經過設置tableA的元表的__index字段爲tableB,當讀tableA中沒有的字段時就會從tableB中讀該字段。

能夠先建立一個空table,而後經過設置元表的方式,建立一個對象,當訪問該對象沒有的字段時就會在類中尋找。

lua代碼:
-- 建立對象方法
function new( moduleName )
	local obj = {}
	setmetatable(obj,{__index = moduleName})
	return obj
end


繼承


在Lua中繼承也能夠經過設置元表的方式實現。

lua代碼:
-- 繼承
function extend( child, parent ) 
    setmetatable(child,{__index = parent})
end


靜態與非靜態


靜態成員與非靜態成員的區別就在於:是否能夠經過類名訪問,若是能夠經過類名訪問則是公有靜態成員,不然是非公有靜態成員或非靜態成員。而在Lua中類名就是模塊名稱,若是能夠「模塊名.成員名」形式訪問則是公有靜態成員。

lua代碼:
module("Student",package.seeall)

-- 公有靜態成員變量(可經過模塊名訪問)
flag = 1
-- 私有靜態成員變量(外部不可訪問)
local flag2 = 2

-- 非靜態成員方法(須要傳self)
function init(self, name)
    -- 非靜態成員變量    
	self.name = name
end

-- 靜態成員方法(不須要傳self)
function getFlag()
	return flag
end

-- 非靜態成員方法
function getName(self)
	return self.name
end

tools.lua
-- 建立一個對象並初始化
function create( moduleName, ... )
	local obj = new(moduleName)
	obj:init( ... )
	return obj
end

調用代碼:
    require "utils/tools"
    require "Student"

    -- 訪問公有靜態成員變量    
    cclog("flag = %d",Student.flag)
    -- 訪問靜態方法    
    cclog("flag = %d",Student.getFlag())
    -- 建立一個Student對象    
    local obj = create(Student,"xiaoming")
    -- 經過對象訪問公有靜態成員變量    
    cclog("falg = %d",obj.flag)
    -- 訪問非靜態成員變量    
    cclog("name = %s",obj.name)
    -- 訪問非靜態成員方法    
    cclog("name = %s",obj:getName())


打印結果:




1.靜態成員變量與非靜態成員變量的區別在於:該變量是存在模塊的環境中,仍是存在self中。


2.靜態成員方法與非靜態成員方法的區別在於:該方法是否須要傳self。


3.訪問靜態成員與非靜態成員

訪問模塊中的成員均可以經過「模塊名.成員名稱」的方式訪問,但訪問模塊中 非靜態成員方法時,經過「self:成員名稱()」的方式會更方便(注意:":"只是爲了語法便利,做用只是把self做爲方法的第一個實參,與「模塊名稱.(self)」沒什麼區別)。

注意:在Lua中原本並無靜態與非靜態這個概念。
相關文章
相關標籤/搜索