0

この関連する質問を見つけました:継承でコンポジションを使用するにはどうすればよいですか?

Objective-C でも同じことをしたいと思います。つまり、 aはGenericViewそのプロパティobjが GenericObject であるSpecializedViewことを知っており、 a はまったく同じobjプロパティが であることを知っていSpecializedObjectます。

より明確になる例を次に示します。

//
//  Example.m

#import <UIKit/UIKit.h>

/* HEADER */

// Electrical Machine
@interface ElectricalMachine : NSObject {
}
- (void)plugIn;

@end

// Toaster
@interface Toaster : ElectricalMachine {
}
- (float)getThermostat;

@end

// GenericView
@interface GenericView : NSObject {
    ElectricalMachine *machine;
}
- (void)doSomethingGeneric;
@property (nonatomic, retain) ElectricalMachine *machine;

@end

//SpecializedView
@interface SpecializedView : GenericView {
}
- (void)doSomethingSpecialized;
@end


/* IMPLEMENTATION */

// GenericView
@implementation GenericView

@synthesize machine;

- (void)doSomethingGeneric {
    Toaster *toaster = [[Toaster alloc] init];
    [toaster plugIn];
    self.machine = toaster;
    [toaster release];
}

@end

// SpecializedView
@implementation SpecializedView

- (void)doSomethingSpecialized {
    /* ERROR HERE
     * Incompatible types in initialization
     * 'ElectricalMachine' may not respond to '-getThermostat'
     */
    float r = [machine getThermostat];
    r = r;
    // ...
}

@end

SpecializedViewご覧のとおり、マシンのプロパティはElectricalMachineではなく であるため、最後にエラーが発生しますToaster

ご助力ありがとうございます!

古い質問

これが私の質問の最初のバージョンです。

私は次の一般的な見解を持っています:

@interface GenericView {
    GenericObject obj;
}

- (id)doSomething;

また、次の特殊なビューもあります。

@interface SpecializedView : GenericView {
}

- (id)doSomethingElse;

次のオブジェクトがあります。

@interface GenericObject {
}

- (id)plugIn;

および次の特殊なオブジェクト:

@interface SpecializedObject : GenericObject {
}

- (float)toastTime;

GenericView で GenericObject を処理し、SpecializedView でそれが SpecializedObject であることを認識して同じオブジェクトを処理するとします。

実装を示して説明しましょう。

GenericView doSomething

- (id)doSomething {
    [obj plugIn];
}

SpecializedView doSomethingElse

- (id)doSomethingElse {
    // ERROR here
    float time = [obj toastTime];
}

次の警告が表示されます: 'GenericObject' may not response to '-toastBread' および次のエラー: Incompatible types in assignement

obj の型を GenericObject として定義したので、これは論理的です。GenericView では GenericObject のメソッドを、SpecializedView では SpecializedObject のメソッドを使用できるようにしたいと考えています。プロパティを追加せずに、obj が処理される GenericView の GenericObject である必要があり、SpecializedView で処理される SpecializedObject である必要があることを正確にする方法はありますか? どうやってそれをしますか?

4

1 に答える 1

0

Objective-C は動的型付け言語であり、メソッドはコンパイル時ではなく実行時に解決されます。inSpecializedViewobj実際にタイプのオブジェクトである場合SpecializedObject( として宣言されていてもGenericObject)、実際にはtoastBreadメッセージに応答します。コンパイラは警告を生成しますが、無視できます。

SpecializedViewが と の両方GenericObjectsを持っている可能性がある場合は、 がメッセージ ( から継承)を使用して応答することを確認SpecializedObjectsできます。objtoastBreadrespondsToSelector:NSObject

if ([obj respondsToSelector:@selector(toastBread)]) {
    [obj toastBread];
}
于 2009-10-30T14:19:30.670 に答える