美文网首页
Lua实现继承

Lua实现继承

作者: 我和我的火柴 | 来源:发表于2021-03-27 20:29 被阅读0次

Lua元表使用 中的__index元方法可以实现面向对象和继承关系:

  • lua中没有类的概念,只有table,但可以用__index模拟类和对象:
local A = {}

function A:new(name)
    self.__index = self

    return setmetatable({ 
        name = name 
    }, self)
end

function A:print()
    print("name is ", self.name)
end

local a = A:new("Tony")
a:print()
-- output: name is Tony

A和a两个表之间的关联是这样的:

image

这里name是表a的key,print是表A的函数,当用a调用print时,找到的元表A中的__index(指向A自己)中的print方法,而方法内的self是调用者a,所以self.name是a的name。
(Lua中的self)


  • 两个类之间同样可以用__index实现继承关系:
local Person = {}
function Person:new(name)
    self.__index = self
    return setmetatable({
        name = name
    }, self)
end
function Person:print()
    print("name is ", self.name)
end

local Student = setmetatable({}, Person)
Student.super = Person
function Student:new(name, score)
    self.__index = self

    local student = self.super:new(name)
    student.score = score

    setmetatable(student, self)
    return student
end
function Student:print()
    self.super.print(self)
    print("score is ", self.score)
end

local s = Student:new("Tony", 98)
s:print()

-- output :
-- name is Tony
-- score is 98

用图表示这三个table的关系:

image

在调用s:print()时,由于s没有print这个函数,找到的s的元表Student的__index(指向Student自己)中的print函数,

首先执行self.super.print(self),这里self是调用者s,s没有super这个属性,同样是找到元表Student中的super即Person,执行Person的print打出name is Tony(这里用点调用函数传入的第一个参数self还是s,Lua中的self

然后第二行打印score即s.score;

当继承关系比较复杂时,这种调用显得比较混乱且容易出问题,可以封装一个Object基类,实现继承关系链,方便方法调用且减少出问题的几率。


  • 实现面向对象的Object基类:

将设置__index和setmetatable的操作统一写在Object类里,方便使用和减少出错,一共有两处:

  1. 实现继承关系时:在Object的方法中实现继承关系(设置__index和元表的一系列操作)
local Object = {}
Object.__index = Object
function Object:new()
end

function Object:extend()
    local SubClass = {}
    for k, v in pairs(self) do
        if k:find("__") == 1 then
            SubClass[k] = v
        end
    end
    SubClass.__index = SubClass
    SubClass.super = self
    setmetatable(SubClass, self)
    return SubClass
end

  1. 创建实例对象时:用__call实现构造方法(new方法中的设置元表)
function Object:__call(...)
    local object = setmetatable({}, self)
    object:new(...)
    return object
end

上面Student的例子可以写成:

local Person = Object:extend()
function Person:new(name)
    Person.super.new(self)
    self.name = name
end
function Person:print()
    print("name is ", self.name)
end

local Student = Person:extend()
function Student:new(name, score)
    Student.super.new(self, name)
    self.score = score
end
function Student:print()
    Student.super.print(self)
    print("score is ", self.score)
end

local s = Student("Tony", 98)
s:print()
-- output :
-- name is Tony
-- score is 98

ps. 要注意的是,在子类调用父类方法时,尽量都是用 ClassName.super 而不要用self.super,因为lua里的self是不确定的。(当传入self调用的父类方法中也有self.super时会进入死循环)Lua中的self

转载作者:正谦

相关文章

  • 2018-08-02

    lua实现继承,重载和多态(上) *讲到lua的继承等面向对象的实现,首先得讲一下lua中的几个元方法和元表. s...

  • Lua实现继承

    Lua实现继承 我们知道在Lua脚本语言中是没有对象这个概念的。但是Lua为我们提供了一堆的元方法,可以实现类的继...

  • Lua实现继承

    Lua元表使用 中的__index元方法可以实现面向对象和继承关系: lua中没有类的概念,只有table,但可以...

  • Lua实现继承

    Lua元表使用[https://www.jianshu.com/p/ef03c9d33c67] 中的__index...

  • lua实现多继承

    lua对于面向对象的支持主要通过table来实现,每个table都是一个对象,对于继承,lua有元表的机制,通过s...

  • 对lua中类、实例、继承的理解

    lua底层有__index等表,去实现类,实例、继承。但是比较绕。 参考1.1.5.Lua语言面向对象之复制表的方...

  • 2018-08-06

    lua实现继承,重载和多态(下) 上一篇讲了,lua的几个元方法和元表, 这里我们直接手动实现一个类方法, 可以创...

  • Lua实现继承的方法

    lua通过元表实现继承 lua查找一个表元素的规则如下 1.在表中查找,如果找到,则返回这个元素 2.判断该表是否...

  • Lua 元表和元方法

    table 作为 Lua 中唯一的数据结构,我们可以利用 table 实现面向对象编程中的类、继承、多重继承等等。...

  • 使用xmake优雅地描述工程

    描述语法 xmake的描述语法基于lua实现,因此描述语法继承了lua的灵活性和简洁性,并且通过28原则,将描述作...

网友评论

      本文标题:Lua实现继承

      本文链接:https://www.haomeiwen.com/subject/oigyhltx.html