面向对象三大特性包括:封装、继承、多态。
还有在Lua中如何创建类和实例化,这里一一介绍
1.1、Lua类的创建和实例化
Test1.lua
--name,age就相当于字段。eat就相当于方法
person = {name = 'Ffly',age = 20}
function person:eat()
print(self.name .. '该吃饭饭了,饿死了')
end
--这个方法用于实例化使用
function person:new()
local self = {}
--使用元表,并把__index赋值为person类
setmetatable(self,{__index = person})
return self
end
Test2.lua
--加载模块Test1.lua(类似于C#中的using引用)
--LuaStudio默认从软件根目录下加载
require "Test1"
--实例化person类
person1 = person:new()
person1:eat() --正常输出
1.2、Lua封装
--对age字段进行封装,使其只能用get方法访问
function newPerson(initAge)
local self = {age = initAge};
--三个方法
local addAge = function(num)
self.age = self.age + num;
end
local reduceAge = function(num)
self.age = self.age - num;
end
local getAge = function(num)
return self.age;
end
--返回时只返回方法
return {
addAge = addAge,
reduceAge = reduceAge,
getAge = getAge,
}
end
person1 = newPerson(20)
--没有使用额外的参数self,用的是那里面的self表
--所以要用.进行访问
person1.addAge(10)
print(person1.age) --输出nil
print(person1.getAge()) --输出30
1.3、Lua继承
--基类person,boy类继承于person
person = {name = "default",age = 0}
function person:eat()
print(self.name .. '该吃饭饭了,饿死了')
end
--使用元表的 __index完成继承(当访问不存在的元素时,会调用)
function person:new(o)
--如果o为false或者o为nil,则让o为{}
o = o or {}
setmetatable(o,self)
--设置上面self的__index为表person
self.__index = self
return o
end
--相当于继承
boy = person:new()
--name在boy里找不到会去person里面找
print(boy.name) --输出default
--修改了person里的值,并不会影响boy里面的值
boy.name = 'feifei'
print(person.name) --输出default
print(boy.name) --输出feifei
1.4、Lua多态
person = {name = "default",age = 0}
--重载
--简单方法:lua中会自动去适应传入参数的个数,所以我们可以写在一个方法里面
function person:eat(food)
if food == nil then
print(self.name .. '该吃饭饭了,饿死了')
else
print(self.name .. '喜欢吃:' .. food)
end
end
function person:addAge(num)
if num == nil then
self.age = self.age + 1
else
self.age = self.age + num
end
end
print(person:eat())
print(person:eat("大西瓜"))
person:addAge()
print(person.age)
person:addAge(5)
print(person.age)
--重写
function person:new(o)
--如果o为false或者o为nil,则让o为{}
o = o or {}
setmetatable(o,self)
--设置上面self的__index为表person
self.__index = self
return o
end
boy = person:new()
boy.name = "Ffly"
boy:eat() --调用基类eat方法
--相当于重写eat方法
function boy:eat()
print('小男孩' .. self.name .. '快要饿死了')
end
boy:eat() --调用派生类eat方法
2、Lua面向对象进阶
2.1、class.lua的实现
class代码参考于云风大大的博客。
class.lua
--表_class的key为类,value为类的虚表
local _class={}
--为什么要使用虚表呢?
--[[
使用虚表的话,那么类本身的元素会是稳定的,
所有的变化都在虚表中进行,
这样 封装了变化、也便于继承的实现
]]
function class(super)
--要创建的类class_type
local class_type={}
--构造函数,基类
class_type.ctor=false
class_type.super=super
--class_type类型的虚表,虚表中包含class_type中的元素
local vtb1={}
_class[class_type]=vtb1
--给类设置元表
--在给表添加新元素时,会在虚表中也添加
setmetatable(class_type,{
__newindex = function(t,k,v) vtb1[k] = v end,
__index = function(t,k) return vtb1[k] end,
})
--super不为空,表示为继承
if super then
setmetatable(vtb1,{__index=
function(t,k)
--从基类找要找的元素,找到就放入派生类虚表中
local ret=_class[super][k]
vtb1[k]=ret
return ret
end
})
end
--给类型class_type创建实例对象
--1、先依次从最顶层基类中调用构造方法
--2、然后设置元表
class_type.new=function(...)
--生成这个类对象
local obj={}
do
local create
--递归调用构造函数
create = function(c,...)
--super不为空,表示有基类
if c.super then
create(c.super,...)
end
--调用构造函数
if c.ctor then
c.ctor(obj,...)
end
end
create(class_type,...)
end
--设置obj的 __index为class_type的虚表
setmetatable(obj,{ __index=_class[class_type] })
return obj
end
return class_type
end
person.lua
require "class"
--创建基类person
person = class()
person.name = "Ffly"
person.age = 20
--设置person类的构造函数
function person:ctor()
print("person:ctor 调用");
end
function person:eat()
print(self.name .. "很饿,想吃东西")
end
--创建派生类boy,基类为person
boy = class(person)
function boy:ctor()
print("boy:ctor 调用");
end
function boy:eat()
print("boy " .. self.name .. "很饿,想吃东西")
end
--创建完两个类后,就可以使用了。
--创建boy类的实例boy1
boy1 = boy.new()
boy1:eat()
--[[
输出:
person:ctor 调用
boy:ctor 调用
boy Ffly很饿,想吃东西
]]
2.2、单例模式的实现
Boy.lua
require "class"
boy = class()
--单例模式的实现
boy.Instance = function()
if (nil == boy.m_instance) then
boy.m_instance = boy.new();
end
return boy.m_instance
end
function boy:ctor()
end
Singleton.lua
require "boy"
local b1 = boy.Instance()
local b2 = boy.Instance()
if b1==b2 then
print("相等")
else
print("不相等")
end
--输出相等
|
请发表评论