2010-03-29 37 views
1

我想創建類汽車,車輛的init方法,以及飛機具有以下屬性:iPhone - 一個抽象類

  • 汽車和飛機是車輛的兩個子類。
  • 汽車和飛機都有一個initWithString方法。
  • Car和Airplane的initWithString方法可接受的輸入字符串不重疊。
  • 汽車是「幾乎抽象的」,因爲任何初始化的實例應該是汽車或飛機。
  • 根據輸入的字符串,可以將一個字符串傳遞給Vehicle並獲取Car的實例,Airplane的實例或nil。

我應該更喜歡的任何特定設計模式?特別是對於Vehicle的initWithString和/或newVehicleWithString方法。

回答

4

您需要的是「類集羣」模式。你的Vehicle initWithString:方法可能看起來像這樣:

- (id) initWithString:(NSString *)mode { 
    // note that we don't call [super init] in a class cluster. 
    // instead, we have to release self because it's an unwanted Vehicle instance 
    [self release]; 
    if([mode isEqualToString:@"wheels"]) { 
    return [[Car alloc] initWithString:@"wheels"]; 
    } 
    if([mode isEqualToString:@"wings"]) { 
    return [[Airplane alloc] initWithString:@"wings"]; 
    } 
    return nil; //alternately, raise NSInvalidArgumentException 
} 
+0

我認爲這很有用,注意在這種情況下,重寫alloc並返回一個特殊的singleton實例會分配和初始化正確的類並返回它,可能會更有效。 – 2010-03-30 01:13:12

+1

的確如此,但這聽起來很像過早的優化。 – codewarrior 2010-03-30 01:17:05

+0

似乎這些日子,每個人都必須把一切都變得極端。現在,當有一個非常明確和容易「優化」的機會時,人們不會考慮簡單的解決方案。在你的情況下,你正在創建並在100%的時間內扔掉物體。我們需要平衡,人們:)在這種情況下,無論如何它會更乾淨和更正確 - alloc也是創建類集羣的地方​​,而不是init。 – 2010-03-30 01:30:45

0

引用超類的子類不是一個好主意。

如果你真的必須這樣做,你至少應該使用類似方法,如vehicleWithString:

事實上,我懷疑另一種方法(使用vehicle initWithString:來創建汽車或飛機的實例)可行。

+1

超類引用子類的東西是類集羣如何在整個可可中工作。 – Chuck 2010-03-29 23:03:30

+0

恰恰相反!這是一個名爲「類集羣」的設計模式,其中'Vehicle initWithString:'決定哪個子類返回一個實例。這種模式在整個Cocoa中使用,尤其是NSString。 – codewarrior 2010-03-29 23:05:24

+0

這正是我喜歡SO的原因,謝謝。但是,據我所知,Cocoa中的類集羣中的子類都是私有的。我仍然認爲在公共子類中使用這種模式有點危險。 – 2010-03-30 00:44:38