LUA中的OOP(2) --- 单继承
来源:互联网 发布:千岛湖惨案 知乎 编辑:程序博客网 时间:2024/05/15 17:42
其实单继承是前几天看的了,但是因为比较忙再加上今天下午摆弄了半天C#,所以一直没有总结。
前面说过lua本身只是一个脚本语言,在它上面玩OOP其实需要深入语言,利用语言提供的机制来实现OOP的机制。这次来看看针对OOP中单继承机制的一个实现方案,这个是根据《lua中文手册》上单继承那部分文章演化而来,我觉得书上的办法虽然看着很灵活但是却不够严格,或者说在语义上不够严谨,所以我做了一些改进,这个方案中我尽量靠近高级语言描述OOP时的文法,大家看完可以体会体会。
结合LUA自身的特点,在这个方案中,我定义了3个函数作为对OO本身描述的原语,分别是: CreateObject用于从指定的原型对象中生成一个新的对象实例;Inherit用于让子原型对象继承指定的父原型对象;Inheritable用于声明某个原型对象是可被继承的。单继承的实现就依靠在定义 原型对象时使用这些原语来达到目的。
<-------------Code Begin------------->
--[[
下面我们先来看3个原语的实现
]]-
-- 传递原型对象和待创建对象,返回新创建的对应类型的对象
function CreateObject(proto_type, newobj)
newobj = newobj or {};
setmetatable(newobj, proto_type);
return newobj;
end
--让child原型对象继承base原型对象
function Inherit(child, base)
setmetatable(child, base)
end
--使得一个原型对象具备"可被继承性"
function Inheritable(proto_type)
proto_type.__index = proto_type
--为proto_type的metatable添加写保护,只允许读取metatable而不许设置,保证继承链不被破坏
proto_type.__metatable = proto_type
end
--首先定义human类的原型
do
local function __print_age(self)
print(string.format("human age = %d", self.age))
end
local function __set_age(self, value)
self.age = value;
end
local function __get_age(self)
return self.agel;
end
human = {
age = 0,
set_age = __set_age,
print_age = __print_age,
get_age = __get_age,
};
--在这里用Inheritable原语声明human原型对象是可以被继承的
Inheritable(human)
end
--然后定义继承者Woman类的原型
do
local function __print_age(self)
print(string.format("woman age = %d", self.age))
end
woman = {
print_age = __print_age,
};
--在这里用Inheritable声明woman原型对象是可以被继承的,在我们这个例子中是否使用这个原语对能否继承其他原型对象并无
--影响。
Inheritable(woman);
--这一步是关键,使用Inherit原语,声明woman原型对象将会继承human原型对象,只要human原型对象使用过
--过Inheritable原语声明自己是可被继承的,那么这里只要用Inherit()原语即可完成继承。
Inherit(woman, human);
end
-- 最后我们来看测试代码,用CreateObject()原语为woman原型对象创建两个新实例对象
newobj0 = CreateObject(woman, {age = 25});
newobj1 = CreateObject(woman, {age = 24});
-- 运行下面的代码可以看到, newobj0和newobj1的属性相互不冲突,是两个完全独立的对象,同时也都继承了
--父类human的方法和属性,特别的,如果各位在上面woman类的定义里注释掉 print_age = __print_age 这句,
--就会发现这个继承本身就带有了一定虚函数的性质(这么说其实尚不严格),允许子类重新实现父类中的成员方法。
newobj1:print_age();
newobj0:print_age();
newobj0:set_age(15);
newobj1:print_age();
newobj0:print_age();
<-------------Code End------------->
原理:很简单,还是靠metatable。Inheritable和Inherit原语都是针对原型对象的metatable在做手脚。Inheritable原语会为原型对象增加__index成员并令
其指向自身,Inherit原语会让子原型对象的metatable指向父类,联合这两点就能看出,当在子类中查找某个不存在成员时会自动去
其父类中查找(因为设置了metatable指向父类,而父类的__index指向其自身)。更进一步的使用递归归纳法可以证得这2个继承原语的组合对任意深度的单继承均有效。
- LUA中的OOP(2) --- 单继承
- LUA中的OOP(3) --- 多继承
- OC中的OOP之 --- 继承
- LUA中的OOP(1) --- 类和对象
- LUA单继承与多继承实验
- OOP---- 继承
- OOP-继承
- python中的单继承
- lua中的继承之baseclass.lua分析
- cocos2dx开发中的lua继承
- quick lua中的类继承
- lua中的继承和多继承
- Lua 实现单例 (userdata) 多继承单例
- Java编程手册—OOP中的继承和多态
- C# OOP模型(传说中的继承封装多态)
- lua单例2
- lua实现OOP编程
- lua-8 OOP/数据库
- LeetCode3_Longest Substring Without Repeating Characters
- 11.1.2.2 使用不可变数据结构
- CPU发卡总结
- linux sed命令详解
- 根据属性名称获取其在对象中所存放的值
- LUA中的OOP(2) --- 单继承
- mybatis一对多
- Android Dependencies
- JAVA IO
- [java]实现导出Excel文件和XML文件
- (4) Flume1.5.0的安装、部署、简单应用(含伪分布式、与hadoop2.2.0、hbase0.96的案例) (1-8)
- linux ethtool 工具
- 企业应用监控利器-ZABBIX
- 【delphi】TComboBox 输入文本并触发change事件后光标总会移动到最前面的问题