注:只是仿照,并不是真正的面向对象
C#中是用this表示当前类的对象,Lua中使用self
点(.)与冒号(:)的区别:前者需要手动调用self参数,后者隐藏self参数
借助table实现面向对象:
Person = { -- 创建一个person类
name = "",
age = 0
}
function Person.Setvalue(self, _name, _age) --类方法
self.name = _name
self.age = _age
end
function Person.Getvalue(self) --类方法
return self.name, self.age
end
local p1 = Person --创建对象
p1.Setvalue(p1, "小明", 18)
local n, a = p1.Getvalue(p1)
local p2 = Person --创建对象
p2.Setvalue(p2, "小东", 22)
local nn, aa = p2.Getvalue(p2)
print(nn .. '\t' .. aa)
print(n .. '\t' .. a)
使用冒号(:)形式:
Person = { -- 创建一个person类
name = "",
age = 0
}
function Person:Setvalue(_name, _age) --类方法
self.name = _name
self.age = _age
end
function Person:Getvalue() --类方法
return self.name, self.age
end
local p1 = Person --创建对象
p1:Setvalue("小明", 18)
local n, a = p1:Getvalue()
local p2 = Person
p2:Setvalue("小东", 22)
local nn, aa = p2:Getvalue()
print(nn .. '\t' .. aa)
print(n .. '\t' .. a)
说明:这里所谓的创建对象就是直接调用了父类表,创建多个对象也是指向同一处地方,一个对象数据变化其他对象也跟着变。所以这样的面向对象,创建一个对象还行,创建多个对象不适用。
继承实现:
利用__index实现继承:将子类表的元表和__index方法都设置为父类自身,子类没有的东西会自动搜索__index表(即父类表),相当于父类表的东西都继承给了子类表。
-----------父类----------------
Person = {
name = "",
age = 18,
gender = ""
}
function Person:New(tab)
tab = tab or {}
setmetatable(tab, self)
self.__index = self
return tab
end
function Person:Eat()
print(self.name .. "都会吃东西")
end
function Person:Init(name, age, gender)
self.name = name
self.age = age
self.gender = gender
end
function Person:GetInfo()
return self.name, self.age, self.gender
end
--------------子类对象----------------
Chinese = Person:New({height = 180, looklike = "帅气"})
Chinese:Init("中国人", 5000, "男")
Chinese:Eat()
American = Person:New({})
American:Init("美国人", 1000, "女")
American:Eat()
function American:Sing()
print(self.name .. "唱歌挺好听的")
end
American:Sing()
print(Chinese:GetInfo())
print(American:GetInfo())
中国人都会吃东西
美国人都会吃东西
美国人唱歌挺好听的
中国人 5000 男
美国人 1000 女
说明:
1、子类有单独的表,一个子类表中数据的改变不会影响其他子类变化;
2、相当于直接实例化出来了子类对象,能调用父类表中的变量与方法,同时自身也可以定义新的变量与方法。
网友评论