如何处理双重构成和继承?

时间:2009-10-30 13:44:41

标签: objective-c oop inheritance composition

我发现了这个相关的问题:How do I use composition with inheritance?

我想对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,计算机属性为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'可能无法响应'-toastBread' 并出现以下错误:     分配中不兼容的类型

这是合乎逻辑的,因为我已经将obj的类型定义为GenericObject。我希望能够使用GenericView中GenericObject的方法,以及SpecializedView中SpecializedObject的方法。有没有办法确定obj必须是要处理的GenericView中的GenericObject,并且必须是SpecializedObject才能在SpecializedView中处理,而不添加属性?你会怎么做?

1 个答案:

答案 0 :(得分:0)

Objective-C是一种动态类型语言,方法在运行时解析,而不是编译时。如果在SpecializedView中,obj实际上是SpecializedObject类型的对象(即使它被声明为GenericObject),它实际上会响应toastBread } 信息。编译器将生成警告,但您可以忽略它。

如果SpecializedView可能包含GenericObjectsSpecializedObjects,则可以确定 obj使用toastBread回复respondsToSelector: NSObject消息(继承自if ([obj respondsToSelector:@selector(toastBread)]) { [obj toastBread]; } ):

{{1}}