我有一个带有工厂的抽象超类,它返回一个子类的实例。是否有可能只在超类中实现一个方法?例如,在下面的代码中,是否可以删除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()时,会遗漏一个错误。此外,在扩展而不是实现超类时,省略子类实现不会导致错误。但是使用工厂方法,扩展不是一种选择。
答案 0 :(得分:3)
要继承Element
中Wind
的功能,您需要在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");
}
要想为子类生成构造函数和在接口/框架类中生成默认实现的工厂构造函数,这是一个常见问题。 List
和Map
接口存在此问题,并通过公开ListBase
和MapBase
解决了这个问题。当您将超类公开给其他库中的其他用户时,我认为这是最佳解决方案。如果它只由你自己内部使用,我将在超类中使用私有/非默认命名的生成构造函数。