面向对象的特征
- 封装、继承、多态、抽象
- Lua语言虽然不是传统的oo类型语言,但可以利用一些方法(table + function)实现面向对象的特性。
最简单的例子 - 定义对象的属性、方法
person = { name = "fanfan", age = "18"} --定义属性:姓名、年龄
person.intro = function() -- 定义方法: 自我介绍
print("我是"..person.name..)
end
--方法的第二种写法--
function() person.intro()
print("我是"..person.name..)
end
--方法的第三种写法--
person = { name = "fanfan", age = "18", intro = function()
print("我是"..person.name..)
end
}
print(person.age) --18
person.intro() -- 我是fanfan
--缺点:其他对象不能使用该方法(传入的参数是person)
--改进如下:person传递给self -> 变成冒号
--self对应当前传递进来的表
function person: intro()
print("我是"..self.name)
end
a = person
a:intro() --对象a也用冒号,这样a也能使用该方法
a.intro(a) -- 通过.调用,只能通过参数将table赋值给self
创建构造函数
Person = { name = "fanfan", age = "18"} --大写Person
function Person: intro() --大写Person
print("我是"..self.name)
print("我的年纪是"..self.age)
end
-- 创造新对象时,新对象创建新表,把Person的值赋给新对象
-- 调用属性时,如果t中不存在,那么会在_index指定的table(self新对象)里找
function Person:new(o) --大写Person
local t = o or {} -- t是空,去index里找self. 传进来有o,按照o添加
--setmetatable(t, {__index = self}) -- 与下面写的方式相同
setmetatable(t,self)
self._index = self
return t
end
person1 = Person:new(nil) --把Person的值赋给新对象。不写nil也可以,默认nil
person2 = Person:new({weight = 100}) --添加了一个新属性,走到o的逻辑。
person1.name = "keke" -- 修改值,原person表不变
person1:intro() --也可以引用该方法 记得是冒号!!!!
print(person2.weight) -- 输出100
继承
Student类,继承自Person
Student = Person:new() --Student类,继承自Person
Student.grate = 1 --Student类,定义新属性
stu1 = Student:new() --新建对象stu1
stu1:eat() --继承Person的方法
print(stu1.grage) --继承Student的属性