Objective-Cの多重継承


88

2つのクラスがあり、1つはmethodAを含み、もう1つはmethodBを含みます。新しいクラスでは、メソッドmethodAとmethodBをオーバーライドする必要があります。では、どうすれば目的Cで多重継承を実現できますか?構文に少し混乱しています。

回答:


136

Objective-Cは多重継承をサポートしていないため、必要ありません。構成を使用:

@interface ClassA : NSObject {
}

-(void)methodA;

@end

@interface ClassB : NSObject {
}

-(void)methodB;

@end

@interface MyClass : NSObject {
  ClassA *a;
  ClassB *b;
}

-(id)initWithA:(ClassA *)anA b:(ClassB *)aB;

-(void)methodA;
-(void)methodB;

@end

次に、関連するivarでメソッドを呼び出すだけです。より多くのコードですが、objective-Cの言語機能としての多重継承はありません。


8
多くの場合、特にコードで多くの単体テストを行う場合は、コンポジションは継承よりも優れたアプローチです。クラス自体を再定義せずに実装を簡単に交換できるという点で、柔軟性が大幅に向上します。たとえば、モックオブジェクトのClassAとClassBを交換する場合に特に便利です。実行時にも、スワップアウト実装(FTPFileStoreとLocalFileStoreなど)を構成するときれいになります。だからといって、継承に場所がないことを意味するわけではありませんが、多重継承の必要性から、設計を再考する必要があると思われます;)
d11wtq 2010年

1
分かりません。あなたはインスタンス化する必要はありませんClassAClassB?呼び出しんmethodA:MyClass呼んで自動的に何とかmethodA:上のClassA
ザクダンス2013

1
いいえ、ただしOOPが本来機能するはずだった方法であるメッセージパッシングを通じて、動作を共有できます。すぐに継承が必要だと考えるのではなく、代わりにコンポジションを使用したソリューションを検討すると、プログラムをより保守しやすい方法で構造化し始めることがわかります。もちろん、ObjCは、それを使用することが正しい場合のための基本的な継承を持っています。
d11wtq 2013


1
d11wtq、素晴らしい答えです!さらに、メッセージ転送では、methodAとmethodBを再実装するステップをスキップできます。わずかな作業で、メッセージを適切なオブジェクトに自動的に転送できます。 developer.apple.com/library/mac/documentation/Cocoa/Conceptual/...
arsenius

3

これは、singletonPatternを「親」としてコーディングする方法です。基本的に、プロトコルとカテゴリの組み合わせを使用しました。

追加できないのは新しい「ivar」だけですが、関連付けられたオブジェクトでプッシュできます。

#import <Foundation/Foundation.h>
@protocol BGSuperSingleton
+(id) singleton1;
+(instancetype)singleton;
@end

@interface NSObject (singleton) <BGSuperSingleton>

@end

static NSMutableDictionary * allTheSingletons;

+(instancetype)singleton
{
    return [self singleton1];
}
+(id) singleton1
{
    NSString* className = NSStringFromClass([self class]);

    if (!allTheSingletons)
    {
        allTheSingletons = NSMutableDictionary.dictionary;
    }

    id result = allTheSingletons[className];

    //PO(result);
    if (result==nil)
    {
        result = [[[self class] alloc]init];
        allTheSingletons[className]=result;
        [result additionalInitialization];
    }
    return result;
}

-(void) additionalInitialization
{

}

クラスにこのBGSuperSingletonを「継承」させたいときはいつでも、次のようにします。

#import "NSObject+singleton.h"

そして追加 @interface MyNewClass () <BGSuperSingleton>


2
カテゴリは多重継承ではありません。これらは、既存のクラスにメソッド/関数を追加する方法です。多重継承により、3番目のクラスを1つ以上のクラス(変数を含む)の組み合わせにすることができます。カテゴリーが好きです。カテゴリは非常に便利です。しかし、それらは多重継承ではありません。
ロイドサージェント2013年

しかし、UIViewControllerのサブクラスも「サポート」できます。この場合、シングルトンパターンが必要です。
Septiadi Agus

技術的には、すべてのNSManagedObjectが「呼び出し可能」[objシングルトン]です。プロトコルのサポートで希望するものを設定します。とにかく多重継承と同じくらい良いです。これは、子クラスで親のインターフェースと実装の両方をサポートする場合にのみ必要です。実装のみの場合は、明らかに構成が適切です。
Septiadi Agus

<BGSuperSingleton>のようなプロトコルを追加するだけでは、クラスは「シングルトン」メソッドを呼び出せなくなります。まだ実装する必要があります...
CommaToast

-4

プロトコルについて知っていますか、プロトコルは多重継承を実装する方法です


12
+1「階層的に関連していないクラス間の類似点を取り込むため。」developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/...
pokstad

7
この場合、両方のメソッドがオーバーライドされるので、プロトコルがうまくいきます。他の場合、継承を使用してコードを再利用する場合、プロトコルは役に立ちません。ただし、これは通常、クラスのスーパークラスに互いに継承させるか、それらを組み合わせることによって解決できます。通常、サブクラスが実際に2つのクラスとコードを共有している場合は、それを正しく行う方法があります。
jake_hetfield 2012年

プロトコルをカテゴリまたは構成のいずれかと組み合わせることができます。
Septiadi Agus

-1は、多重継承のためのプロトコルがまったく存在しないためです。同様にJAVAInterfacesは多重継承を提供または模倣するものではありません。
thesummersign

1
@FreeAsInBeerアップル独自のドキュメント からプロトコルは、任意のクラスが実装することを選択できるプログラムインターフェイスを宣言します。プロトコルにより、継承によって遠く離れた2つのクラスが相互に通信して特定の目標を達成することが可能になります。したがって、これらはサブクラス化の代替手段を提供します。ご覧のとおり、Appleは 明示的にサブクラス化、つまり継承を使用しています。おそらくこれを彼自身の答えに含めることで、ニケシュは彼の議論を明確にするのに役立つでしょう
ハニー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.