super
とは、Objective-Cがself
オブジェクトのメソッドを呼び出しますが、super
が呼び出されたクラスと同じクラスのメソッドの実装は使用しないことを意味します。やや紛らわしいが、この考えてみます。
@interface Grandparent : NSObject
- (void)a;
- (void)b;
@end
@implementation Grandparent
- (void)a {NSLog(@"Grandparent a");}
- (void)b {NSLog(@"Grandparent b");}
@end
@interface Parent : Grandparent
@end
@implementation Parent
- (void)a {NSLog(@"Parent a"); [super a];}
@end
@interface Offspring : Parent
- (void)a {NSLog(@"Offspring a"); [super a];}
- (void)b {NSLog(@"Offspring b"); [super b];}
@end
-[Offspring b]
の実装を見てください。それは[super b]
を呼び出しますが、Parent
は-b
の実装を提供しません。 Objective-Cは-[Grandparent b]
が見つかるまで階層を調べ続け、それを実行します。 Grandparent
にこのメソッドがない場合は、NSObject
となります。
-[Offspring a]
を呼び出すことを検討してください。メッセージが記録された後、Parent
の実装である[super a]
が呼び出されます。そのメッセージは、Parent
で定義されているメソッドでそれを実行するため、[super a]
を呼び出します。-[Grandparent a]
(インスタンスは実際にはOffspring
オブジェクトですが)が検索されます。
これは、いずれのNSObject
子孫に対しても、super
経由でメッセージを呼び出すと、メソッドの実装がNSObject
になる可能性があることを意味します。 Objective-CにはNSObject
(例えばNSProxy
)から派生しないクラスがあるため、super
は常にになります。
Xcodeでいくつかの調整をして再度チェックしたところ、「スーパー」は明示的に実装されたメソッドをバイパスするようです。たとえば、Parentが[super a]を行う新しいメソッド "c"を定義して実装していて、main.mで[offspring1 c]を実行すると、superはParentの "a"をバイパスし、 "Grandparent"の "a"をチェックしますたとえParentがOffspringの最初のスーパークラスであっても、私は明示的な実装が "super"を使用する鍵だと思いますか? – Rexroth
@Rexroth私が言ったように、それはメソッドが定義されているクラスのスーパークラスから始まります。あなたの 'c'メソッドは' Parent'で定義されているので、 'super'解像度は' Grandparent'で始まります。 –
したがって、私がOffspringで "c"を再び定義すると、コードが完全に同じであっても、オーバーライドまたは "再定義"とみなされますか?私がOffspringの@implementationで明示的に "c"を実装すると、 "c"が "再定義された"クラスのスーパークラスであるParentクラスから開始されるからです。 – Rexroth