LoginSignup
6
6

More than 5 years have passed since last update.

スーパークラスのメソッドを上書きして返り値の型を狭め、キャストを不要にする

Last updated at Posted at 2013-07-19

あるメソッドの返り値の型が事前に分かっている型よりも“広い”ために、わざわざキャストをしなければならないことがある。

たとえば、-[NSDocumentController sharedDocumentController] メソッドは、通常 NSDocumentController 型のオブジェクトを返すにもかかわらず、返り値の型が id になっている。また、 NSWindowController の自前のサブクラスにおいて、 NSWindow のサブクラスを扱うことが分かっているのに、 -window メソッドの返り値の型が NSWindow のままになっているということもあるだろう。これらのメソッドの返り値を扱うにはダウンキャストが必要になり、煩わしい:

[(NSDocumentController *)[NSDocumentController sharedDocumentController] newDocument:self];

[[(MyWindow *)[myWindowController window] myWindowMethod];

このような場合、サブクラスで同名のメソッドを宣言することで返り値の型を狭めることができる(実装は不要):

@interface MyDocumentController : NSDocumentController

// + (id)sharedDocumentController から返り値の型を狭める
+ (instancetype)sharedDocumentController;

@end

@interface MyWindowController : NSWindowController

// - (NSWindow *)window から返り値の型を狭める
- (MyWindow *)window;

@end

型を狭めることでダウンキャストが不要になる:

[[MyDocumentController sharedDocumentController] newDocument:self];

[[myWindowController window] myWindowMethod];

このように、サブクラスはスーパークラスから継承したメソッドの返り値や引数の型を変えることができる。ただし変更後の型は変更前の型のサブクラスでなければならない。

なお、既存のクラスにカテゴリを追加してメソッドの型を変えようとしても効果はない:

@interface NSApplication (TypeNarrowing)

// - (id<NSApplicationDelegate)delegate から返り値の型を狭めようとしても…
- (MyAppDelegate *)delegate;

@end

...

- (void)foo {
  // 返り値の型は id<NSApplicationDelegate> のまま
  [[NSApplication sharedApplication] delegate];
}
6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6