我有一个继承自Baseclass BaseClass的子类SubClass。
BaseClass有一个初始化程序,如下所示:
-(id)init {
self = [super init];
if(self) {
[self commonInit];
}
return self;
}
-(void)commonInit {
self.goodStuff = [[NSMutableArray alloc]init];
}
SubClass执行其初始化程序,如下所示:
-(id)init {
self = [super init];
if(self) {
[self commonInit];
}
return self;
}
-(void)commonInit {
self.extraGoodStuff = [[NSMutableArray alloc]init];
}
现在,我从未参加过适当的Objective-C课程,但我是电气工程专业的程序员,所以我做了。我开发的服务器端应用程序主要是用Java编写的,所以我可能会通过Java原则看到OO世界。
初始化SubClass时,它调用BaseClass init,我的期望是 - 因为对我的继承意味着BaseClass的特性传递给SubClass - 在BaseClass init期间将调用BaseClass中的commonInit方法。
不是。我可以*理解也许 - 可能 - 伸展我的想象力,为什么它不会。但是,那么 - 为什么它不是基于OOP的原则?如果不是正在运行的代码类的实例,那么“self”代表什么?
好的,所以 - 我不会认为Objective-C正在开发的版本是错误的。那么,那么在这种情况下我应该使用的模式是什么?我希望SubClass有两个主要部分--BaseClass所具有的goodStuff以及它应该得到的extraGoodStuff。
显然,在这种情况下我一直在使用错误的模式。我是否打算公开commonInit(这让我对封装原则感到疑惑 - 为什么要暴露一些在Java世界中至少会被视为“受保护”的东西以及应该只为每个实例调用一次的东西)?
我最近遇到了类似的问题,并试图搞砸了它,但现在 - 我真的很想知道我是否已经完全掌握了我的原则和概念。
请帮忙。让我澄清一下 - 当我在super上调用init时,我得到的自我最终成为SubClass。我在调试时可以看到等等。
在这种情况下,重写方法的模式是什么?哪里有一些可以从超类中的几个init方法调用的常见初始化?我是否必须将代码放在init的每个变体中?
答案 0 :(得分:3)
self
和super
只是指向内存位置的指针,它们指向分配对象的同一地址,但Objective-C编译器会对它们进行特殊处理:
super
以第一个超类型开始重载解析,即。父类型(在这种情况下为BaseClass
)。
self
在指针指向的当前运行时类型处启动重载解析。这就是为什么您无法从BaseClass commonInit
致电BaseClass
,因为self
指向SubClass
。如果你想这样做,你应该commonInit
SubClass
来[super commonInit]
。{/ p>
答案 1 :(得分:1)
self
在您的示例中的BaseClass构造函数中的类型为SubClass
,因此[self commonInit]
调用SubClass
'commonInit覆盖,而不是BaseClass
'commonInit方法。