二重の構成と継承に対処する方法は?
-
22-07-2019 - |
質問
この関連する質問を見つけました:コンポジションを継承で使用するにはどうすればよいですか?
Objective-Cでも同じことを行います。つまり、 GenericView
はそのプロパティ obj
がGenericObjectであり、 > SpecializedView
は、まったく同じ 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
のマシンプロパティは Toaster
ではなく ElectricalMachine
であるため、最後にエラーが発生します。
ご協力ありがとうございました!
古い質問
ここに私の質問の最初のバージョンがあります。
次の一般的なビューがあります:
@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」は「-toastBread」に応答しない場合があります そして次のエラー: 割り当ての互換性のないタイプ
objの型をGenericObjectとして定義しているため、これは論理的です。 GenericViewではGenericObjectのメソッドを使用し、SpecializedViewではSpecializedObjectのメソッドを使用できるようにしたいと考えています。プロパティを追加せずに、objをGenericViewのGenericObjectで処理し、SpecializedObjectでSpecializedViewで処理する必要があることを正確にする方法はありますか?どうしますか?
解決
Objective-Cは動的に型指定された言語であり、メソッドはコンパイル時ではなく実行時に解決されます。 SpecializedView
の場合、 obj
は実際には SpecializedObject
型のオブジェクトです( GenericObject
として宣言されている場合でも) 、実際には toastBread
メッセージに応答します。コンパイラは警告を生成しますが、無視できます。
SpecializedView
に GenericObjects
と SpecializedObjects
の両方がある場合、 obj
は、 respondsToSelector:
メッセージ( NSObject
から継承)を使用して toastBread
に応答します:
if ([obj respondsToSelector:@selector(toastBread)]) {
[obj toastBread];
}