2010-03-29 63 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