Lua 面向对象(实现类的创建和实例化、封装、继承、多态)

您所在的位置:网站首页 如何实现封装类 Lua 面向对象(实现类的创建和实例化、封装、继承、多态)

Lua 面向对象(实现类的创建和实例化、封装、继承、多态)

2023-04-28 08:34| 来源: 网络整理| 查看: 265

目录 1、Lua面向对象基础 1.1、Lua类的创建和实例化 1.2、Lua封装 1.3、Lua继承 1.4、Lua多态 2、Lua面向对象进阶 2.1、class.lua的实现 2.2、单例模式的实现

面向对象三大特性包括:封装、继承、多态。 还有在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 --输出相等


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3