2011-02-06 14 views
0

私はこの質問を読んでいて、遭遇する問題はありません。 why does initializing subclasses require calling the super class's same init function?Objective Cの設計されたイニシャライザはどのように機能しますか?

私が読んで理解したところから。すべてのクラスには独自の設計された初期化子があります。 この場合、クラスに初期化子が複数ある場合。私はこのような "Shape.h"クラスを持っているとしましょう。

- (id) init 
{ 
    return [self initWithHeight: 0]; 
} 

- (id) initWithHeight: (int) h 
{ 
    return [self initWithHeight:h withWidth:0]; 
} 

- (id) initWithHeight: (int) h withWidth: (int) w 
{ 
    if(self = [super init]); //since the superclass is NSObject, I use init as designated initializer 
    { 
     [self setHeight:h]; 
     [self setWidth:w]; 
    } 
return self 
} 

また、 "Shape.h"クラスから "Rectangle.h"という名前の新しいクラスをサブクラス化します。 私は " - (id)initWithHeight:(int)hとWitdh:(int)w"という "Shape.h"指定クラスを持っているので、 "Rectangle"の[super init]に使う必要があります。 h "クラスの権利?それはこのようになります。 「Rectangle.h」で

- (id) initWithHeight: (int) h withWidth: (int) w 
{ 
    return [self initWithHeight: h withWidth: w withColor:nil]; 
} 

- (id) initWithHeight: (int) h withWidth: (int) w withColor: (NSString *) c 
{ 
    if(self = [super initWithHeight:h andWidth:w]) 
    { 
     [self setHeight:h]; 
     [self setWidth:w]; 
     [self setColor:c]; 
    } 
return self; 
} 

私は(Shape.hある)スーパーのinit指定された上書きや「Rectangle.h」指定クラスに合わせてそれをカスタマイズします。この方法が正しく動作し、ループが発生しないか?それがそうであれば、スーパークラス指定のinitに従わずに[super init]を使用すると、なぜループするのかをリンクの誰かに説明することができます。

私は混乱を招いて申し訳ありません。私は本当にコンセプトをよく理解することができません。

答えて

1

あなたのコードは正しいようですが、試してみましたか? 指定されたイニシャライザは、他のすべてのイニシャライザによって使用される "最も完全な"イニシャライザです。これは、RectangleクラスとShapeクラスの両方で行われます。 したがって、Rectangle initで行うことは、super(Shape)イニシャライザを使用してクラスを初期化することです。次に、自己が正しいかどうかをチェックします(何らかの理由でsuperが返された場合、たとえばw/hパラメータが正しくない場合がありますが、これはShapeでは当てはまりません)。次に、適切な色を割り当てます。 Shapeのイニシャライザで既に行われているので、HeightとWidthを再割り当てする必要はありません。新しいクラスがスーパーの設定を無効にする必要がある場合にのみ、これを行うのが理にかなっています(理由は問わない)。 だからあなたのコードが正しいのですが、二組の削除:私は「Rectangle.h」クラスで指定された初期化を使用するのであれば、それはスーパーのinitを呼び出して使用して高さと幅の値を設定します



     [self setHeight:h]; 
     [self setWidth:w]; 
+0

をスーパークラスはinitを指定します。値を現在のクラス(サブクラス)に渡し、colorの値をサブクラス "Rectangle.h"に割り当てます。だから私のアプローチは、スーパークラスのinitを上書きするだけで正しい私のコードで正しいですか?これが正しい場合、スーパークラスが最終的に指定されたinitを呼び出すので、self = [super initWithHeight:(int)hとWitdth:w]をself = [super init]に置き換えることができます。 – sayzlim

+0

いいえ、正しくありません。 Infact if Rectangle initWithHeight:幅:Colorは[super init]を呼び出し、次にRectangleを返します。Rectangle initWithHeight:呼び出す幅が呼び出されます。Rectangle initWithHeight:Width:Colorは真円度につながります。あなたは、ShapeのinitWithHeight:andWidthによって実行される完全な初期化を利用することはできません。 Appleの "The Objective-C programming language"より、このルールに従ってください。一般原則:クラス内の指定された初期化子は、スーパークラスへのメッセージを介して、スーパークラス内の指定された初期化子を呼び出す必要があります。 – viggio24

+0

これらの2行の違いは何ですか? [super init]と[super initWithHeight:AndWidth:]を入力します。後で循環性を引き起こさないのはなぜですか?つまり、[super init]を使用すると、Shape.h initWithHeight-> initWithHeight:andWidthが呼び出されて同じものになりますか? – sayzlim

関連する問題