如何使用工厂构造函数扩展抽象 class?

How to extend an abstract class with factory constructor?

情况如下:

abstract class A {
  void doSomething() => print('Do something..');
}

class B implements A {
  @override
  void doSomething() => print('Do something already..');
}

class C extends A {
}

我有一个摘要class A. Class B 实现了 A。因此它覆盖了 doSomething() 方法。 Class C 扩展 A.

一切正常,直到我将工厂构造函数添加到 class A:

abstract class A {
  factory A() => new B();

  void doSomething() => print('Do something..');
}

这会导致我的 IDE (IntelliJ IDEA) 出错:

The generative constructor expected, but factory found

我的第一个想法是为 class C 创建构造函数,我会在其中为 A 调用工厂构造函数。这可能吗?

我在尝试扩展 Exception class 时遇到了同样的问题。它还有一个工厂构造函数:

abstract class Exception {
  factory Exception([var message]) => new _ExceptionImplementation(message);
}

这就是为什么要创建我的自定义异常,我必须实现异常 class 而不是扩展它,这让我很困惑。

我还想澄清一个术语问题。 我可以说从Bclass的角度来看,A是一个接口,所以B正在实现接口A。 但是,从 C class 的角度来看,A 是一个抽象 class 所以 C 扩展了抽象 class A。这些说法正确吗?

谢谢。

德米特里。

如果 class 没有构造函数,则会隐式添加生成构造函数。如果 class 具有显式构造函数,则不会添加生成构造函数。 你有两个选择。

  • 使工厂构造函数成为命名工厂构造函数并添加普通构造函数
abstract class A {
  void doSomething() => print('Do something..');
  factory A.name() => new B();
  A();
}
  • 或者命名普通构造函数并从扩展 class
  • 中显式调用它
abstract class A {
  void doSomething() => print('Do something..');
  factory A() => new B();
  A.protected();
}

class C extends A {
  C() : super.protected();
}

尝试 DartPad

你说的对。如果你实现一个 class 它作为一个接口,如果你扩展它它作为一个基础 class.

我不知道它有用,但它解决了我的问题。而且我知道有很多解决方案可能是最糟糕的解决方案。 :) 但我想和你分享

有时后端 API returns 模型相同但值不同。 像这样。

Map<String,dynamic> map1 = {
  "version": "2.16.0",
  "language_1":"Dart",
  "framework_1":"Flutter",
};


Map<String,dynamic> map2 = {
  "version" : "10.0.1",
  "language_2":"javaScript",
  "framework_2":"NodeJs",
};

我需要 D 模型,因此扩展了来自 D

的其他模型
class D{
  D({
    this.language,
    this.frameWork,
    this.version,
  });
  String? language;
  String? frameWork;
  String? version;
}

扩展来自 D

的模型
class A extends D{
  A();
  
  factory A.fromJson(Map<String,dynamic> json) => C.fromJsonForA(json);

}


class B extends D{
  B();
  
 factory B.fromJson(Map<String,dynamic> json) => C.fromJsonForB(json);
}

并在其他classC

中编写factory构造函数
class C extends D implements B,A{
  C({
    String? language,
    String? frameWork,
    String? version,
  }):super(
    language:language,
    frameWork:frameWork,
    version:version,
  );
  
  factory C.fromJsonForB(Map<String,dynamic> json){
    final c = C.protected(json);
    c.frameWork = json['framework_2'];
    c.language = json['language_2'];
    return c;
  }
  
  
  factory C.fromJsonForA(Map<String,dynamic> json){
    final c = C.protected(json);
    c.frameWork = json['framework_1'];
    c.language = json['language_1'];
    return c;
  }
  
  
  factory C.protected(Map<String,dynamic> json){
    return C(
      version: json["version"],
    );
  }
}

我用过:)

  A modelA = A.fromJson(map1);
  B modelB = B.fromJson(map2);
class Example {
  Example._();
  
  static printModel(D model){
    print("${model.language} : ${model.frameWork} version : ${model.version}");
  }
}