结合案例讲解Lua中如何实现面向对象

首先我们要明白面向对象是一种思想,其核心概念如下:

封装:用程序语言把一类事物的方法和属性描述出来;

继承:子类可以继承父类方法

多态:对于继承同一父类的子类其内部实现各有不同(不同的对象执行父类的同一个方法产生了不同的结果)

一、如何实现面向对象中的封装

print("people is aready")

people={        --虽然people是一个table,但是我们可以用面向对象的一个思想,将它看作一个抽象类:people类

    name=nil,

    age=nil

}

function people.new(cname,cage)

    local p={}

    p.name=cname

    p.age=cage

    return p

end

function people.eat()

    print("eating...")

end



local zhangsan=people.new('zhangsan',15)--其实张三是一个table但是我们用面向对象的思想,将它看作对象

local lisi= people.new('lisi',20)--李四同样是people抽象类实例化出来的一个对象

print(zhangsan.name,zhangsan.age)

print(lisi.name,lisi.age)

 

 

上面的案例,我们就是把table人 以面向对象的思想来看,他就是一个人类的抽象类
而zhangsan 和 lisi 就是人类实例化后的对象

 

二、如何在lua中实现面向对象的继承

2.1.我们可以看到执行上面的逻辑后,p并不会执行people中的eat方法

print("people is aready")

people={        --虽然people是一个table,但是我们可以用面向对象的一个思想,将它看作一个抽象类:

people类

    name=nil,

    age=nil

}

function people.new(cname,cage)

    local p={}

※    setmetatable(p,people)--将table p 和table people关联了起来(这样子可以让两个table实现继承的关系)

※    people.__index=people--程序去元表里寻找__index键,然后去这个键值对应的表里面寻找这个eat方法

    p.name=cname

    p.age=cage

    return p

end

function people.eat()

    print("eating...")

end





local zhangsan=people.new('zhangsan',15)--其实张三是一个table但是我们用面向对象的思想,将它看作

对象

local lisi= people.new('lisi',20)--李四同样是people抽象类实例化出来的一个对象

print(zhangsan.name,zhangsan.age)

print(lisi.name,lisi.age)

zhangsan.eat()

 

 

※2.2.Lua中“:”冒号的用法

 

--在lua的编程中  ":"冒号和"."的去区别是什么:

-- :表示默认传入一个变量self,所以上面的代码可以这样子更改

function people:eat()

    print(self.name.."eating...")

end

zhangsan:eat()

 

 

三、通过Metatable 元表与元方法来实现多态:

在Lua中,每个table都可以关联一个metatable。metatable是一个普通的table,可以包含一些特殊的字段(也称为元方法),这些字段定义了对应操作的行为。通过设置metatable,我们可以对table对象进行元操作的重载,实现自定义的行为。

常用元方法

  • __index:当访问一个table中不存在的索引时触发。
  • __newindex:当给一个table中不存在的索引赋值时触发(赋值会失败)。

 1.__index:

__index 主要用于对table的查询:
如果子表中的元素不存在,lua就会调用元表中的__index,去元表中查找对应的元素。
这里的元素并不局限于字段,也包括方法和table。

local tableChild={
    age=20
}
local tableParent={
    __index={
        name='Jay',
        age=25
    }
}
setmetatable(tableChild,tableParent)
print(tableChild.name)--输出结果:Jay
--因为子表中没有name,所以去它的元表的index里找有没有name这个字段
print(tableChild.age)--输出结果:20
--因为子表中有age,所以直接输出子表中的value而不会再去元表中寻找覆盖

2.__newindex:

__newindex主要用于对table的赋值更新

如果想对子表中不存在的索引赋值时,lua就会调用元表中的__newindex元方法,
如果该方法是一个函数,就会执行这个方法

local animal={

    name="dog"

}

local o={}

o.__newindex=function ()--给o增加一个元方法

    print("__newindex Is Working")

end

setmetatable(animal,o)--给animal增加一个元表,把o作为animal的元表设置进去

animal.age=29--__newindex Is Working
--因为animal这个table中没有age这个属性,所以赋值时回去找元表,然后元表中又有__newindex这个元方法,便调用元方法

print(animal.name)--dog
print(animal.age)--nil


local b={}

local c={}

local people={

    name="eason"

}

b.__newindex=c--给b增加一个__newindex元方法,这个元方法指向table  c

setmetatable(people,b)--给people指定一个元表b

people.age=20

print(people.age)--nil

print(c.age)--20

--__newindex的两种用法

--1.__newindex可以指向一个方法

--2.__newindex可以指向一个table,然后将值赋给指向的table

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值