3

我有一个带有返回子类实例的工厂的抽象超类。是否可以有一个只在超类中实现的方法?例如,在下面的代码中,是否可以删除 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() 时,会出现关于它丢失的错误。此外,当扩展而不是实现超类时,省略​​子类实现不会导致错误。但是对于工厂方法,扩展不是一种选择。

4

1 回答 1

4

要从Elementin继承功能Wind,您需要扩展或混合Elementin 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类以及一个空名称的生成构造函数。在这种情况下,mixins 不是一个好的选择,因为当 mixins 不能有构造函数时,没有很好的方法来做final。actionactaction

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");
}

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

于 2015-11-12T07:00:19.377 回答