[Lua系列]Lua的面向对象

119 阅读2分钟

面向对象的特征

  • 封装、继承、多态、抽象
  • 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的属性