0

我发现了这个相关的问题:如何将组合与继承一起使用?

我想对 Objective-C 做同样的事情,也就是说 aGenericView知道它的属性obj是 GenericObject,并且 aSpecializedView知道相同的obj属性是 a 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机器属性是 a ElectricalMachine,而不是 a 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];
}

专门查看做其他事情

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

我将收到以下警告:“GenericObject”可能无法响应“-toastBread”和以下错误:分配中的类型不兼容

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

4

1 回答 1

0

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

如果SpecializedView可能同时具有GenericObjects和,则SpecializedObjects可以确保使用消息obj响应(继承自):toastBreadrespondsToSelector:NSObject

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