【问题标题】:iPhone -- init method of an abstract classiPhone——抽象类的init方法
【发布时间】:2010-03-30 07:15:47
【问题描述】:

我想创建具有以下属性的 Car、Vehicle 和 Airplane 类:

  • Car 和 Airplane 都是 Vehicle 的子类。
  • Car 和 Airplane 都有一个 initWithString 方法。
  • Car 和 Airplane 的 initWithString 方法可接受的输入字符串不重叠。
  • Vehicle 是“几乎是抽象的”,因为任何初始化的实例都应该是 Car 或 Airplane。
  • 可以将字符串传递给 Vehicle 并返回 Car 实例、Airplane 实例或 nil,具体取决于输入字符串。

我应该更喜欢任何特定的设计模式吗?特别是对于 Vehicle 的 initWithString 和/或 newVehicleWithString 方法。

【问题讨论】:

    标签: iphone objective-c abstract-class


    【解决方案1】:

    您需要的是“类集群”模式。您的 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
    }
    

    【讨论】:

    • 我认为需要注意的是,在这种情况下,重写 alloc 并返回一个特殊的单例实例,该实例分配并初始化正确的类并返回它。
    • 没错,但这听起来很像过早的优化。
    • 现在似乎每个人都必须把一切都做到极致。现在,当有一个非常清晰和容易“优化”的机会时,人们甚至不会考虑简单的解决方案。在您的情况下,您 100% 的时间都在创建和丢弃对象。我们需要平衡,人们 :) 在这种情况下,无论如何它会更干净、更正确——alloc 也是创建类集群的地方​​,而不是在 init 中。
    • 我同意不创建一次性对象是显而易见的事情。苹果的类集群也确实是这样工作的,从[NSDictionary alloc] 等人返回一个单例占位符实例。但换句话说,我让计算机丢弃所有这些对象,这样我就不必创建一个单例占位符类。
    • 好吧,我可以通过在车辆中根本没有 initWithString 方法来实现这两种方式。 . .而是有一个 newVehicleWithString 方法来分配和启动正确的子类。
    【解决方案2】:

    从超类引用子类不是一个好主意。

    如果你真的必须这样做,你至少应该使用像vehicleWithString:这样的类方法。

    事实上,我怀疑其他方法(使用 vehicle initWithString: 创建 Car 或 Airplane 的实例)是否可行。

    【讨论】:

    • 超类引用子类是类集群在整个 Cocoa 中的工作方式。
    • 恰恰相反!这是一种称为“类集群”的设计模式,Vehicle initWithString: 决定返回哪个子类的实例。这种模式在整个 Cocoa 中都有使用,尤其是 NSString。
    • 这正是我喜欢 SO 的原因,谢谢。但是,据我所知,Cocoa 中类簇中的子类都是私有的。我仍然认为在公共子类中使用这种模式有些危险。
    猜你喜欢
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2012-09-21
    • 2012-09-16
    • 2011-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多