lua虽然没有面向对象的概念,但我们实现面向对象并不困难

一下内容我参考了多处lua教程,很多教程讲解模糊晦涩,我整理了以下以简明的说明方式完成lua面向对象这部分的内容,希望大家喜欢

面向对象OOP

学习过Java,C#,Ruby等的同学可能不会对面向对象陌生,如果你是第一次接触面向对象?
那么我总结一下就是:将事物抽象成类,将特征抽象为字段和属性。
在Lua中,最强大的就是table这种数据结构了,来看下面这个例子:

Cat={name="defalut",color="白色"}
function Cat.say()
    print(Cat.name..'  '..Cat.color..':','喵喵喵~')
end
Cat.name='小白'
Cat.say()

运行结果为:小白 白色: 喵喵喵~

在例子中,我们创建了一张表,并在表中提供2个字段和一个函数,并通过表名.字段名调用字段和方法,这像不像 一个静态类呢?
以下是Csharp的一个类似的静态类:

class Program
{
    static void Main(string[] args)
    {
        Cat.name = "小白";
        Cat.color = "白色";
        Cat.Show();
    }
}

static class Cat
{
    public static string name;
    public static string color;

    public static void Show()
    {
        System.Console.WriteLine("{0}  {1}   喵喵喵~", name, color);
    }
}

分析一下:之所以是静态类是因为我们只在创建表的时候创建了一个对象,后面无论我们进行操作我们都没有创建一个新对象!

创建对象

function Cat:new()
    local o={}
    setmetatable(o,self)
    self.__index=self
    return o
end

function Cat:say()
    print(self.name..'  '..self.color..':','喵喵喵~')
end

local ca=Cat:new()
ca:say()

在上面的例子中,我们首先添加了一个Cat:new的函数,这类似于我们Csharp中的构造函数,
在构造函数中,我们主要做以下几件事:

  • 创建空表对象
  • 设置空表的元表
  • 设置_index
  • 返回空表对象

在每次创建对象时,我们都通过:new函数来创建。
在这里我们使用到了:setmetatable(o,self)这句话的意思是设置o的元表为自己(也就是Cat对象),self.__index=self是设置元方法索引为Cat对象,这2句话总体就是让对象o具有Cat对象的属性和函数。
当然元表,元方法的作用还有很多,也远比这要复杂,感兴趣可以自己去了解~

继承和多态

让我们来看这个例子:

-- 基础类
Human={name='defaultName',age=0}
function Human:new()
    local o={}
    self.__index=self
    setmetatable(o,self)
    return o
end

function Human:show()
    print('Base:','Name:',self.name,'Age:',self.age)
end

local myhum=Human:new()
myhum.name="小蓝"
myhum.age=20
myhum:show()

-- 派生类
Chinese=Human:new()
function Chinese:new()
    local o={}
    setmetatable(o,self)
    self.__index=self
    return o
end
function Chinese:show()
    print('Chinese:','Name:',self.name,'Age:',self.age)
end

local ch=Chinese:new()
ch.name="小红"
ch.age=15
ch:show()

myhum:show()

ch:show()

local ch2=Chinese:new()

ch2:show()


English=Human:new()

function English:show()
    print('English:','Name:',self.name,'Age:',self.age)
end

local eg=English:new()
eg.name="Fasty";eg.age=22
eg:show()

在lua中基于弱类型的优势,对于函数重写,只需要重新定义一遍函数即可。

至此面向对象的封装,继承,多态都实现咯~