如何在包含工厂方法时访问抽象超类实现?

时间:2015-11-12 05:26:08

标签: dart polymorphism factory interface-implementation

我有一个带有工厂的抽象超类,它返回一个子类的实例。是否有可能只在超类中实现一个方法?例如,在下面的代码中,是否可以删除Wind :: act()?

abstract class Element {
  final String action;    // what it does
  String act() => action; // do it

  factory Element() {
    return new Wind();
  }
}

class Wind implements Element {
  final action = "blows";
  act() => action;  // Why is this necessary?
}

void main() {
  print(new  Element().act());
}

删除Wind :: act()时,会遗漏一个错误。此外,在扩展而不是实现超类时,省略​​子类实现不会导致错误。但是使用工厂方法,扩展不是一种选择。

1 个答案:

答案 0 :(得分:3)

要继承ElementWind的功能,您需要在Element中扩展或混合使用Wind。仅仅实现一个接口不会继承任何实现。

所以,你需要class Wind extends Element { ... }。 目前还不可能,因为Element没有Wind可以用作超级构造函数的生成构造函数。因此,您还需要添加它,并确保初始化该构造函数中的action字段。

class Element {
  final String action;
  Element._(this.action);    // Generative constructor that Wind can use.
  factory Element() = Wind;  // Factory constructor creating a Wind.
  String act() => action;
}
class Wind extends Element {
  Wind() : super._("blows");
}

生成构造函数不需要是私有的,但如果您只在自己的库中声明和使用所有类,那么它也可能是。

另一种选择是让一个单独的ElementBase类包含action字段和act函数以及一个空命名的生成构造函数。在这种情况下,Mixins不是一个好的选择,因为当mixin不能有构造函数时,没有好的方法可以使action成为最终的。

abstract class Element {
  String get action;
  factory Element() = Wind;
  String act();
}
class ElementBase implements Element {
  final String action;
  ElementBase(this.action);
  String act() => action;
}
class Wind extends ElementBase {
  Wind() : super("blow");
}

要想为子类生成构造函数和在接口/框架类中生成默认实现的工厂构造函数,这是一个常见问题。 ListMap接口存在此问题,并通过公开ListBaseMapBase解决了这个问题。当您将超类公开给其他库中的其他用户时,我认为这是最佳解决方案。如果它只由你自己内部使用,我将在超类中使用私有/非默认命名的生成构造函数。