当前位置: 首页 > article >正文

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,执行的也是子类的函数!


http://www.kler.cn/news/363233.html

相关文章:

  • 项目管理新趋势!2024年,Jira与禅道你更倾向谁?
  • 你还在使用存储过程吗?
  • Android Studio USB调试真机映射屏幕画面
  • 国内动态短效sk5,http
  • 多模态大语言模型(MLLM)-Deepseek Janus
  • 技术总结(十一)
  • 记内存泄漏排查,如何用dump文件 分析
  • C++——vector的模拟实现
  • Fuse.js 的原理:背后的算法与机制
  • 什么是 SELinux(安全增强型 Linux)?
  • 如何使用IP代理优化亚马逊平台的操作体验
  • 基于神经网络的农业病虫害损失预测
  • android openGL ES详解——缓冲区VBO/VAO/EBO/FBO
  • openssh openssl zlib 升级至最新版解决安全问题
  • 数字英文验证码识别 API 对接说明
  • Python 基于 Chat Completions API 实现外部函数调用
  • 人工智能在医疗领域的应用:AI模型在高血脂症疾病的预测与治疗决策上的应用
  • C#应用程序实现限制输入法
  • Django的模板的应用
  • Ubuntu18.04:no module named ‘apt_pkg‘(python3.6升级为3.7要注意的事情)
  • Jupyter notebook和Conda使用
  • python写的一个博客系统
  • 大模型开发实战1-QuickStart
  • 零,报错日志 2002-Can‘t connect to server on‘106.54.209.77‘(1006x)
  • Textbus:GitHub上的宝藏项目,构建复杂富文本的不二之选
  • java 提示 避免用Apache Beanutils进行属性的copy。