UnLua实现多态

一、什么是多态
多态其实就是子类重写父类的函数,在运行时,如果通过父类对象调用函数,实际上会根据子类的实际类型调用子类中重写的函数。
二、在父类中定义函数
BP_WeaponBase_C.lua

--父类构造函数
function BP_WeaponBase_C:UserConstructionScript()
	print("BP_WeaponBase_C:UserConstructionScript")
	print(tostring(self))
    self:SpawnBall()	--直接模拟外部调用父类的SpawnBall函数
end
--父类生成球函数	
function BP_WeaponBase_C:SpawnBall()
 	print("BP_WeaponBase_C:SpawnBall")
	print(tostring(self))
	return nil
end

三、子类如何实现多态?
看下面3种情况,但只有一种情况下是对的!

BP_DefaultWeapon_C.lua

1、情况一:子类构造函数不调用父类构造函数。

--子类继承父类
local BP_DefaultWeapon_C = UnLua.Class("BP_WeaponBase")
--子类构造函数
function BP_DefaultWeapon_C:UserConstructionScript()
    print("BP_DefaultWeapon_C:UserConstructionScript")
    print(tostring(self))
end   
--重写父类生成球函数
function BP_DefaultWeapon_C:SpawnBall()
    print("BP_DefaultWeapon_C:SpawnBall")
    print(tostring(self))
end

打印
在这里插入图片描述
只调用子类的构造函数,并没有调用父类构造函数,所以SpawnBall也没有调用

很明显,连父类构造函数都没有调用,并没有实现多态!

2、情况二:子类构造函数用冒号调用父类构造函数。
在子类的构造函数中,添加self.Super:UserConstructionScript()代码

--子类构造函数
function BP_DefaultWeapon_C:UserConstructionScript()
    print("BP_DefaultWeapon_C:UserConstructionScript")
    print(tostring(self))
    self.Super:UserConstructionScript()
end   

打印
在这里插入图片描述
先调用子类的构造函数,子类的self地址是00000BADB6066700
再调用父类的构造函数,父类的self地址是00000BADB6068600,与子类的self不一样
最后调用父类的SpawnBall,传进去的self是00000BADB6068600,即父类的self

虽然调用了父类构造函数,但是当执行self:SpawnBall()时,这里的self是父类的self,所以调用的是父类的函数而不是子类所重写的函数,也没有实现多态!

3、情况三:子类构造函数用点号调用父类构造函数,并将子类的self作为第一个参数传进去。
在子类的构造函数中,修改代码如下:

function BP_DefaultWeapon_C:UserConstructionScript()
    print("BP_DefaultWeapon_C:UserConstructionScript")
    print(tostring(self))
    self.Super.UserConstructionScript(self)
end   

打印
在这里插入图片描述
先调用子类的构造函数,子类的self地址是00000BAD9C969F80
再调用父类的构造函数,父类的self地址是00000BAD9C969F80,即子类的self
最后调用子类的SpawnBall,传进去的self是00000BAD9C969F80,也是子类的self

显而易见,这种调用方式才是UnLua实现多态的正确姿势,在子类中通过点号调用父类构造函数,并把子类的self当作参数传给父类,这样才能在执行self:SpawnBall()时,确保self是子类的self,执行的也是子类的函数!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值