2009-10-30 60 views
0

我發現此相關的問題: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' 不得迴應'toastBre ad' 和以下錯誤: 分配中的不兼容類型

這是合乎邏輯的,因爲我已將obj的類型定義爲GenericObject。我希望能夠使用GenericView中的GenericObject方法和SpecializedView中SpecializedObject方法。有沒有一種方法可以確定obj必須是GenericView中的GenericObject才能被處理,並且必須是SpecializedObject才能在SpecializedView中處理,而無需添加屬性?你會怎麼做?

回答

0

Objective-C是一種動態類型語言,方法在運行時解析,而不是編譯時。如果在SpecializedViewobj實際上是SpecializedObject類型的對象(即使它聲明爲GenericObject),它實際上也會響應toastBread消息。編譯器會產生一個警告,但你可以忽略它。

如果SpecializedView可能同時GenericObjectsSpecializedObjects,您可以使用respondsToSelector:消息(來自NSObject繼承)使確保obj響應toastBread

if ([obj respondsToSelector:@selector(toastBread)]) { 
    [obj toastBread]; 
} 
+0

謝謝您的回答,我想你的解決方案但由於我不明白的原因,這是行不通的。假設我試圖從[obj toastTime]中獲取一個值,並且它不起作用。彙編說:「在作業中不兼容的類型」。我試圖在GenericObject中添加一個抽象方法,但它不起作用。 – charlax 2009-10-30 14:28:50

+0

在你的例子中,'toastTime'返回一個'id'類型的對象,但是你將它分配給一個'float'。一個'id'不是'float'(它實際上是一個指針),因此不能被賦值給'float'類型的變量。 – mipadi 2009-10-30 14:44:44

+0

對不起,我的例子是錯誤的,即使將toastTime返回的類型定義爲'float',它也不起作用。 – charlax 2009-10-31 09:00:24