【问题标题】:How to declare factory constructor in abstract classes?如何在抽象类中声明工厂构造函数?
【发布时间】:2019-10-22 08:58:15
【问题描述】:

我想声明,但不在抽象类中定义工厂构造函数。

就我而言,我想创建一个方法来接受任何实现String toJson() 方法以及fromJson(Map<String, dynamic> data) 工厂构造函数的类。

有什么方法可以在 Dart 中实现这一点? 我正在寻找类似以下的东西,它不是有效的 Dart 代码:

abstract class JsonSerializable {
  factory fromJson(Map<String, dynamic> data);
  String toJson();
}

【问题讨论】:

  • Dart Language Repo 上是否出现过问题,以便他们将来可以添加?

标签: dart


【解决方案1】:

恐怕它不会按照你想要的方式工作。

构造函数不是接口的一部分。它们更像静态成员。 因此,您不能将工厂添加到接口中,并且代码将无法调用工厂构造函数,因为无论如何都要扩展此类型的类型变量。

所以,由于构造函数不能是接口的一部分,构造函数也不能是抽象。抽象只是意味着“使成员成为接口的一部分,但不向类添加实现”。

您可以将工厂声明为普通方法,但只有在已有实例时才能调用它,这可能不是您想要的构造函数。

传递代码的唯一方法是作为函数或对象与方法。因此,如果您想通过 JsonSerializable 类型参数化某些东西,并且希望能够创建这样的对象,您需要传递一个工厂 函数

  T deserialize<T extends JsonSerializable>(
    String json,
    T factory(Map<String, dynamic> data),
  ) {
    return factory(jsonDecode(json) as Map<String, dynamic>);
  }

你然后调用它:

var myValue = deserialize(jsonString, (x) => MyClass.fromJson(x));

(如果 MyClass.fromJson 是一个静态函数而不是构造函数,你可以只写 deserialize(jsonString, MyClass.fromJson),但 Dart 还没有构造函数分离)。

【讨论】:

  • 你有如何使用它的例子吗?
  • Dart Language Repo 上是否出现过问题,以便他们将来可以添加?
  • 任何例子@lrn
【解决方案2】:

正如接受的答案中所建议的,我最终创建了一个由序列化程序为每个类实现的 Serializer&lt;T&gt; 类型:

事实证明,与直接在课程中使用 toJson/fromJson 相比,这有几个好处:

  • 它将序列化逻辑与实际类分离。这意味着更好的代码可读性,因为类只包含与类直接相关的方法 — 序列化程序甚至可以放入自己的文件中。
  • 目前,扩展无法创建构造函数。因此,单独使用序列化程序可以为现有类编写序列化程序,例如 String 或 Flutter 的 Color,您不能只添加 fromColor 构造函数。
  • 这两点结合起来意味着它也适用于代码生成 — 类是手写的,序列化程序可以在单独的文件中生成。

代码示例:

class Fruit {
  Fruit(this.name, this.color);

  final String name;
  final String color;
}

// in another file

class FruitSerializer extends Serializer<Fruit> {
  Map<String, dynamic> toJson(Fruit fruit) {
    return ...;
  }

  Fruit fromJson(Map<String, dynamic> data) {
    return Fruit(...);
  }
}

然后还将序列化程序传递给需要它的代码:

someMethod<T>(Serializer<T> serializer, T value) {
  ...
}

someMethod(FruitSerializer(), someFruit);
final fruit = recreateFruit(FruitSerializer());

显然,您不能将无法序列化的对象传递给代码,因为该方法需要Serializer&lt;T&gt;

【讨论】:

    猜你喜欢
    • 2015-06-02
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    • 1970-01-01
    • 2014-06-09
    • 2018-09-26
    • 2018-11-04
    • 1970-01-01
    相关资源
    最近更新 更多