quick中面向对象理解误区

     由于lua本身并非面向对象语言,为了方便开发者quick用class方法实现了面向对象的模拟,但使用起来还是有些问题要注意的,今天就来分享一下我解决自己的一个理解误区。

基类
Person.lua


local Person = class("Person")
function Person:ctor()
    print("Person:ctor")
    self:init()
end
function Person:init()
    print("Person:init")
end
return Person

子类
Hero.lua


local Hero = class("Hero",require("app.person.Person"))
function Hero:ctor()
    print("Hero:ctor")
    self.super.ctor(self)
    self:init()
end
function Hero:init()
    print("Hero:init")
end
return Hero

测试代码
MainScene.lua


local Hero = require("app.person.Hero")
local MainScene = class("MainScene", function()
    return display.newScene("MainScene")
end)
function MainScene:ctor()
    local hero = Hero.new()
end
return MainScene

当时我认为它的输出应该是:
Hero:ctor
Person:ctor
Person:init
Hero:init
然而当它真正跑起来时答案却是:
Hero:ctor
Person:ctor
Hero:init
Hero:init
这可不是我想要的结果,后来想了想发现调用self.super.ctor(self)的时候其实那个self传递进去的是Hero的引用,所以在Person中调用init时,
那个self并不是Person本身而是传递进来的Hero的引用,所以就出现了那样的结果。
解决问题的办法就是把self.super.ctor(self)换成self.super.ctor(self.super)就行了。

--------------------------------------------朴实的分割线-----------------------------------
上面的理解有些问题,重新编辑,正解在评论区,Hero.super.ctor(self) 和 Hero.super.ctor(Hero) 的区别就看self 和 Hero是不是相同了,但是还是理解的有点模糊,如果有人能够举个例子清晰的解释下就好了。

不好意思 看错了 删除

楼主你这种设计可能会比较混乱。。。 面向对象的多态就是这样的啊。 子类可以重写父类的方法。。问题出现在你的代码设计上 self.super.ctor(self) 这个代码有问题 但并不是改成self.super.ctor(self.super) 而是Hero.super.ctor(self)//否则再继承hero就会死循环…
Hero:ctor
Person:ctor
Hero:init
Hero:init
这个打印也是正确的。。。面向对象的多态就是这样的。。 问题出现在你的代码设计上

首先 lua是没有构造方法的 这个ctor只是模拟构造方法的一个普通方法。 其次即使在java这种有构造方法的语言中在构造方法里调用多态的方法本身就是一个设计上要避免的。。。。

再继承self.super.ctor(self)这个代码确实有问题,但是self.super.ctor(self.super)是没有问题的,受到你的指点,代码改成这样会好理解点Hero.super.ctor(Hero.super)这个我测了没有问题,不知道这样写你怎么看?
但是我觉得设计上不会有什么问题吧,毕竟满足要求的就是最好的。我这个主要是为了保证从基类到子类的每个ctor,init方法都调用到,并且基类的init方法比子类先调用,所以需要公用的成员变量就可以放到基类的init方法里面了。如果我创建了个对象,然而基类的init没走过,谁知道会出什么问题啊。。

在初始化的时候使用多态的概念,即算概念上是正确的,满足不了我要干的活,我觉得也不是什么好事。。

嗯 self.super.ctor(self) 这样的东西确实有问题

你的那个写法 只是解决了这个问题 但是会带来很大的隐患。。比如按照你最后的写法假设Person类继承了CCNode, 但是在Person类中调用CCNode中的方法, 通过Hero调用就会报错。。。。

如果你实际运用中遇到了 问题。。再改回来吧。。。

嗯,如果是这样local Person = class(“Person”,cc.Node)继承CCNode 那么调用Node方法会报错
但是这样不会
local Person = class(“Person”,function()
return display.newNode()
end)
真心谢谢指点啊!学习了不少,请教下你是如何避免基类的init方法不被调用的呢?是干脆不用init初始化么。。还是有其它比较好的方法

现在看起来其实那个init除了带来麻烦,好像也没有什么用,只是以前用C++写的时候习惯了,摔。。。

local Person = class(“Person”, function()
return display.newNode()
end)
function Person:ctor()
self:setNodeEventEnabled(true)
end

local Hero = class("Hero",Person)
function Hero:ctor()
    Hero.super.ctor(self)
end



Hero.new()

比如这个代码 是没有问题的 , 但是改成你的写法就会有问题。。。实测

那样写确实有问题,问题还挺大,哈哈!!!
而且只能用Hero.super.ctor(self)
Hero.super.ctor(Hero)也是不行的,谢前辈指点,学习了:2:

请问一下ctor中传入Hero和传入self有什么区别啊?

楼主你个悲剧,应该这样改吧Hero.super.ctor(self)

嗯嗯,是的