LUA面向对象程序设计(四)多重继承
2014-07-28 16:21
435 查看
在Lua中实现多重继承,可以有多种方案,在pil中,lua作者提供了一种实现多种继承的方案,但我个人认为,这种方案虽然简洁,但并不算得优雅。后来云风(江湖传说很流弊的人)给出了另外一种既简洁又不失优雅的解决方案,其实现方案,深刻把握了oo的思想。但是,风云(我觉得比云风顺口多了-:-)的实现并没有考虑多重继承的情况,在这里,在风云的实现方案的基础上加以扩展,以支持多种继承的情况。
下面先来看看风云的实现:
local _class={} function class(super) local class_type={} class_type.ctor=false class_type.super=super class_type.new=function(...) local obj={} do local create create = function(c,...) if c.super then create(c.super,...) end if c.ctor then c.ctor(obj,...) end end create(class_type,...) end setmetatable(obj,{ __index=_class[class_type] }) return obj end local vtbl={} _class[class_type]=vtbl setmetatable(class_type,{__newindex= function(t,k,v) vtbl[k]=v end }) if super then setmetatable(vtbl,{__index= function(t,k) local ret=_class[super][k] vtbl[k]=ret return ret end }) end return class_type end
通过上面的函数class,就可以方便地在lua中定义一个类了:
base_type=class() -- 定义一个基类 base_type function base_type:ctor(x) -- 定义 base_type 的构造函数 print("base_type ctor") self.x=x end function base_type:print_x() -- 定义一个成员函数 base_type:print_x print(self.x) end function base_type:hello() -- 定义另一个成员函数 base_type:hello print("hello base_type") end
通过下面的方式就可以实现单一的继承:
child=class(base_type) -- 定义一个类 child 继承于 base_type
function child:ctor() -- 定义 child 的构造函数 print("child ctor") end function child:hello() -- 重载 base_type:hello 为 child:hello print("hello child") end
现在就创建一个child类的一个实例:
obj = child.new(1) -- 输出两行,base_type ctor 和 child ctor 。这个对象被正确的构造了。 obj:print_x() -- 输出 1 ,这个是基类 base_type 中的成员函数。 obj:hello() -- 输出 hello child ,这个函数被重载了。
如果想实现多层单一继承,可以继续创建一个类child2,继承于child,这样就可以实现三层的单一继承了。这里class函数只接收小于等于1个参数的情况,想通过上面的class函数实现多重继承,没有办法实现,但是可以在其基础上加以修改以实现之。
主要修改点有:
>将class的参数修改为可变参数,这样便可以接收任意个参数
>需要递归遍历子类的所有父类,然后执行相应的动作
修改后的class代码如下:
local _class={}
function class(...)
local cls = {}
cls.ctor = false --是否存在构造函数
cls.__base = {...} --当前类的基类们,可能一个,可能多个,可能没有
cls.new = function(...)
local obj = {}
do
local create
create = function(c,...)
if c.__base then
for _, k in pairs(c.__base) do
create(k, ...)
end
end
if c.ctor then
c.ctor(obj, ...)
end
end
create(cls,...)
end
setmetatable(obj, { __index=_class[cls] })
return obj
end
local vtbl={}
_class[cls]=vtbl
setmetatable(cls, {__newindex=
function(t, k, v)
vtbl[k] = v
end
})
if cls.__base then
setmetatable(vtbl, {__index =
function(tab, key)
for _, base_cls in pairs(cls.__base) do
local ret = _class[base_cls][key]
if ret then
vtbl[key] = ret
return ret
end
end
return nil
end
})
end
return cls
end
下面来验证一下,首先我们创建两个基类Name和Account:
Name = class()
function Name:ctor()
print("Name ctor")
self.name = "Smith"
end
function Name:getName()
print("Your name: ".. self.name)
end
Account = class()
function Account:ctor()
print("Account ctor")
self.balce = 1000
end
function Account:deposit(v)
self.balce = self.balce + v
end
function Account:getBalance()
print(self.balce)
end
function Account:withdraw(v)
if self.balce < v then
print(string.format("your account remains %d, not enough %d", self.balce, v))
return
end
self.balce = self.balce - v
end
接下来创建一个子类SpecialAccount,继承上面的两个基类:
SpecialAccount = class(Name, Account)
function SpecialAccount:ctor()
print("SpecialAccount ctor")
end
创建SpecialAccount类的一个实例,并调用其继承的基类的相关接口:
sc = SpecialAccount.new()
sc:getName()
sc:getBalance()
输出结果:
Name ctor
Account ctor
SpecialAccount ctor
Your name: Smith
1000
说明SpecialAccount的对象已经被正确构造了,并且继承了其父类的方法。但是上述的实现仍然存在一点点的瑕疵,比如在子类的函数中不能调用其父类的同名函数,mywcyfl给出了一种解决方案,可以参考一下;还有另一个问题就是在多层继承中,如果给子类的new方法传递参数,那么该参数也会用于父类中的参数的初始化,我也不确定这是否合理。
(全文完)
相关文章推荐
- lua面向对象类,继承和多重继承的实现
- JavaScript 面向对象程序设计(下)--继承与多态
- JavaScript 面向对象程序设计(下)——继承与多态
- 面向对象的程序设计(十一)继承的深入了解,了解他的作用
- JavaScript 面向对象程序设计(下)——继承与多态(转)
- js的面向对象的程序设计之理解继承
- lua面向对象实现-类实例化对象、继承、多态、多继承、lua单例模式
- JavaScript 面向对象程序设计(下)——继承与多态
- JavaScript高级程序设计学习笔记--面向对象的程序设计(二)-- 继承
- lua面向对象实现-类实例化对象、继承、多态、多继承、lua单例模式
- 面向对象的程序设计(七)原型式继承
- JavaScript 面向对象程序设计(下)——继承与多态
- JS Pro - 面向对象的程序设计 - 继承
- javascript高级程序设计第六章:面向对象的程序设计——继承读书笔记
- (转)JavaScript 面向对象程序设计(下)——继承与多态
- JavaScript 面向对象程序设计(下)——继承与多态
- 【JavaScript】面向对象程序设计-继承与多态
- 面向对象程序设计——继承访问机制
- javascript复习笔记六----面向对象程序设计(继承)
- 面向对象的程序设计(九)寄生组合式继承