0

我有一个继承自基类 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 中的 commonInit 方法将在 BaseClass init 期间被调用。

它不是。我可以*有点理解为什么它不会。但是,那么——为什么不基于 OOP 的原则呢?如果不是运行代码的类的实例,“self”代表什么?

好的,所以——我不会争辩说,一个成熟的 Objective-C 版本所做的事情是错误的。那么,在这种情况下我应该使用什么模式?我希望 SubClass 有两个主要部分——BaseClass 拥有的 goodStuff 以及它应得的 extraGoodStuff。

显然,在这种情况下,我一直在使用错误的模式。我是否打算公开 commonInit(这让我对封装原则感到疑惑——为什么要公开至少在 Java 世界中会被认为是“受保护”并且每个实例只应调用一次的东西)?

最近我遇到了类似的问题并试图解决它,但现在——我真的想知道我是否已经把我的原则和概念都放在脑海里了。

一点帮助,请。


让我澄清一下——当我在 super 上调用 init 时,我得到 self 最终成为子类。我在调试时可以看到,等等。

在这种情况下覆盖方法的模式是什么?我在哪里有一些常见的初始化可以从超类中的几个 init 方法调用?我是否必须将代码放入 init 的每个变体中?

4

2 回答 2

3

self并且super只是指向内存位置的指针,它们指向分配对象的相同地址,但它们被 Objective-C 编译器特殊对待:

super在第一个超类型开始重载决议,即。父类型(BaseClass在这种情况下)。

self在指针指向的当前运行时类型开始重载决议。这就是为什么你不能调用BaseClass commonInitfrom BaseClass,因为self指向 a SubClass。如果你想这样做,你应该有commonInitin SubClasscall [super commonInit]

于 2012-12-15T17:10:46.730 回答
1

self在您的示例中的 BaseClass 构造函数中的类型为SubClass,因此[self commonInit]调用SubClass'commonInit override ,而不是BaseClass'commonInit 方法。

于 2012-12-15T17:09:32.947 回答