C#是一个典型的面向对象编程语言,我们可以参考C#来模拟实现Lua的面向对象编程
类和类的创建
Lua中的类是通过表来体现,可以将表当作一个类。
1、包含变量字段和方法。
C#
cs
public class Animal
{
public string name = "动物";
public float height;
public float weight;
public void Say()
{
Console.WriteLine("动物叫声!");
}
}
Lua
Lua
local Animal = {}
Animal.name = "动物"
Animal.height = 0;
Animal.weight = 0;
function Animal:Say()
print("动物叫声!")
end
2、创建类对象
C#
cs
Animal animal1 = new Animal();
animal1.name = "小狗";
Animal animal2 = new Animal();
animal2.name = "小猫";
Animal animal3 = new Animal();
animal3.name = "小鸟";

Lua
为了实现创建类对象,需要对Animal表进行调整
要求:
1、创建的对象(表)要独立。
2、创建的对象可以复用模板类中方法,借助lua中__index元方法的特性实现。
3、模板类提供一个创建对象的接口(例如new方法)。
Lua
local Animal = {}
Animal.name = "动物"
Animal.height = 0;
Animal.weight = 0;
--创建对象方法
function Animal:new()
local obj = {}
setmetatable(obj,Animal)
self.__index = self
obj.name = self.name
obj.height = self.height
obj.weight = self.weight
return obj
end
function Animal:Say()
print(self.name,"叫声!")
end
local animal1 = Animal:new()
animal1.name = "小狗"
local animal2 = Animal:new()
animal2.name = "小猫"
local animal3 = Animal:new()
animal3.name = "小鸟"
animal1:Say()
animal2:Say()
animal3:Say()

3、实现构造函数
在创建对象时调用,传入参数,用于初始化对C#
C#
cs
public class Animal
{
public string name = "动物";
public float height;
public float weight;
public Animal(string _name,float _height,float _weight)
{
name = _name;
height = _height;
weight = _weight;
}
public void Say()
{
Console.WriteLine($"我是:{name} 身高:{height} 体重:{weight}");
}
}
Animal animal1 = new Animal("小狗",111,222);
Animal animal2 = new Animal("小猫", 333, 444);
Animal animal3 = new Animal("小鸟", 555, 666);
animal1.Say();
animal2.Say();
animal3.Say();
Lua
Lua
local Animal = {}
Animal.name = "动物"
Animal.height = 0;
Animal.weight = 0;
--创建对象方法
function Animal:new(_name,_height,_weight)
local obj = {}
setmetatable(obj,Animal)
self.__index = self
obj.name = _name
obj.height = _height
obj.weight = _weight
return obj
end
function Animal:Say()
print(self.name,self.height,self.weight)
end
local animal1 = Animal:new("小狗",111,222)
local animal2 = Animal:new("小猫",333,444)
local animal3 = Animal:new("小鸟",555,666)
animal1:Say()
animal2:Say()
animal3:Say()

继承
先实现一个公共的类继承接口
Lua
--继承公共方法
--child:子类 parent:父类
local Inherit = function (child,parent)
-- 设置新类的元表为父类,实现继承
setmetatable(child,{__index = parent})
-- 将父类保存下来,方便以后使用(例如调用父类方法)
child.base = parent
end
单继承
类似于C#中,一个类只能继承一个基类
Lua
--子类
local list = {}
--父类
local list1 = {
name = "11"
}
function list1:Say()
print("Hello World!")
end
Inherit(list,list1)
list.num = 200
list:Say()
print(list.name,list.base.name,list.num)

多继承
类似于C#中,一个类除了继承一个基类之外还可以继承多个接口。对应到Lua中,相当设置多个元表。但是Lua语法规定:一个表只能有一个元表。但可以通过一些方式来模拟类似的需求:
多个元表进行链接
Lua
--子类
local list = {}
--父类1
local list1 = {
value1 = "11"
}
function list1:Say1()
print("Hello World! 1")
end
--父类2
local list2 = {
value2 = "22"
}
function list2:Say2()
print("Hello World! 2")
end
--父类3
local list3 = {
value3 = "33"
}
function list3:Say3()
print("Hello World! 3")
end
Inherit(list1,list2)
Inherit(list2,list3)
Inherit(list,list1)
print(list.value1)
print(list.value2)
print(list.value3)
list:Say1()
list:Say2()
list:Say3()
多态
C#中,多态性通过方法重载和方法重写实现。Lua 通过元表和 __index
可以很自然地实现重写。
Lua
--子类
local list = {}
--父类1
local list1 = {
value1 = "11"
}
function list1:Say1()
print("Hello World!")
end
--让list继承list1
Inherit(list,list1)
--添加list中Say1函数,相当于重写
function list:Say1()
print("Good Morning")
end
list:Say1()
--打印 Good Morning
封装
定义:把对象的数据和操作代码组合在同一个结构中,这就是对象的封装性。
C#
1、使用访问修饰符(public、protected、private等)来控制成员的操作权限。
2、通过属性封装字段,方法封装操作逻辑,类封装变量、属性、方法等
Lua
1、使用local声明局部变量
2、使用表来封装变量和方法、方法封装操作逻辑
