Lua实现面向对象以及类的继承

0.简单前言

1、面向对象主要四个特征:封装,继承,多态,抽象
2、Lua是种简单精致小巧的语言,其本质是个表(table),变量和方法皆可看作为该表的元素。

P.S. 该博客和代码为个人编写习惯以及为后续博客内容拓展服务考虑,若有错误等不周到的地方还请包涵以及指出。

1.类

尽管可能不太完美,但我们依旧可以通过元表的方式实现类以及类的继承。

-- 元类
local Rectangle = {area = 0, length = 0, breadth = 0}

-- 派生类的方法 new
function Rectangle:new (o,length,breadth)
  local o = o or {}
  setmetatable(o, self)		-- 将Rectangle赋值给要返回的对象作为元表
  self.__index = self		-- 通过 .__index 传递元表元素
  self.length = length or 0
  self.breadth = breadth or 0
  self.area = length*breadth;
  return o
end

-- 派生类的方法 printArea
function Square:printArea ()
  print("矩形面积为 ",self.area)
end

简单结构就是这样,Square类已经继承Rectangle的属性以及方法,同时还拓展出自己的新方法 printArea(),但实际运用起来并不方便。

2.改进

class类

用于构建模板以及进行类的继承

Class.lua

-- params:要实例的类,继承
function class(classname , ...)
    local cls = {}

    local supers = {...}
    for _ , super in ipairs(supers) do
        local superType = type(super)
        if superType == "function" then
            cls.__create = super
        elseif superType == "table" then
            cls.__supers = cls.__supers or {}
            cls.__supers[#cls.__supers + 1] = super
        end
    end

    cls.__index = cls
    cls.__class = classname

    if not cls.__supers then
        -- 没有继承其他类
        -- 添加默认构造函数
        -- __index指向自己不变
        cls.Ctor = function()   end      
    elseif #cls.__supers == 1 then
        -- 单继承的情况
        local super = cls.__supers[1]
        cls = setmetatable(cls , {__index = super})
        cls.super = super		-- 模拟super关键字
    else 
        -- 多继承的情况
        -- 使index指向一个函数,在索引时遍历父类
        cls = setmetatable(cls , {__index = function(_ , key)
            for _ , super in ipairs(cls.__supers) do
                if super[key] then
                    return super[key]
                end
            end
        end})
    end

    cls.New = function(...)
        -- 前面只是将几个类进行合并,因此在实例时还需进行一次元表
        local instance = setmetatable({}, cls)
        instance.class = cls
        instance:Ctor(...)

        return instance
    end

    -- 返回实例
    return cls
end

实验

创建4个脚本A,B,C,D。
使得C继承A,
D继承A,B。

A.lua

A = class(A)

function A:Ctor()
    print("We create a class A!")
end

function A:Fun_A()
    print("This is a function from class A!")
end

return A

B.lua

B = class(B)

function B:Ctor()
    print("We create a class B!")
end

function B:Fun_B()
    print("This is a function from class B!")
end

return B

C.lua

C = class(C , A)                -- 让C类单独继承A类

function C:Ctor()
    print("We create a class C!")
end

function C:Fun_C()
    print("This is a function from class C!")
end

return C

D.lua

D = class(D , A , B)            -- 让D类同时继承A,B类

function D:Ctor()
    print("We create a class D!")
end

function D:Fun_D()
    print("This is a function from class D!")
end

return D

检验

main.lua

-- 实例以及覆写方法
local test_c = C:New()
local test_d = D:New()

-- 子类自身的方法
test_c:Fun_C()
test_d:Fun_D()

-- 子类继承的方法
test_c:Fun_A()
test_d:Fun_A()
test_d:Fun_B()

-- 没有继承的方法
-- test_c:Fun_B()

结果

We create a class C!
We create a class D!
This is a function from class C! 
This is a function from class D! 
This is a function from class A! 
This is a function from class A! 
This is a function from class B! 

若把注释取消,则直接报attempt to call a nil value (method ‘Fun_B’)

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Lua是一种脚本语言,它支持面向对象编程。在Lua中,我们可以通过表(table)来实现面向对象编程。表可以被看作是一个对象,它可以存储任意类型的数据(包括函数),还可以作为其他表的元素。下面是使用Lua实现面向对象的一些基本步骤: 1. 创建一个表,它代表一个类 2. 在这个表中定义一个构造函数,用于创建该类的实例 3. 在这个表中定义其他成员函数和成员变量 4. 在这个表中定义一个元表,用于实现继承和多态 下面是一个简单的例子,展示了如何使用Lua实现一个名为Person的类: ```lua -- 创建一个Person类 Person = {} -- 定义Person的构造函数 function Person:new(name, age) local obj = {} obj.name = name obj.age = age setmetatable(obj, self) self.__index = self return obj end -- 定义Person的成员函数 function Person:sayHello() print("Hello, my name is " .. self.name .. ", I'm " .. self.age .. " years old.") end -- 创建一个Person对象 local person = Person:new("Tom", 20) -- 调用对象的成员函数 person:sayHello() ``` 在这个例子中,我们首先创建了一个空表Person,它代表一个类。然后我们定义了Person的构造函数new,用于创建Person的实例。在构造函数中,我们创建了一个新表obj,并将name和age属性赋值给它。然后我们使用setmetatable函数将obj的元表设置为Person,并将self设置为__index。这样做可以让obj继承Person的成员函数。最后,我们返回obj。 接下来,我们定义了Person的成员函数sayHello,它用于打印出人的姓名和年龄。在最后,我们创建了一个Person对象person,并调用它的成员函数sayHello。 如果你想要继承Person类,你可以创建一个新的表Student,并将它的元表设置为Person。这样做可以让Student继承Person的成员函数和属性。如果你想要重写某个成员函数或属性,你可以直接在Student表中重新定义它们。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值