如何在抽象类中声明工厂构造函数?

Mar*_*cel 6 dart

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

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

有什么办法可以在Dart中实现?我正在寻找类似以下内容的东西,这是无效的Dart代码:

abstract class JsonSerializable {
  factory fromJson(Map<String, dynamic> data);
  String toJson();
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*cel 14

正如已接受的答案中所建议的,我最终创建了一个Serializer<T>由每个类的序列化器实现的类型:

\n

在此输入图像描述

\n

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

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

代码示例:

\n
class Fruit {\n  Fruit(this.name, this.color);\n\n  final String name;\n  final String color;\n}\n\n// in another file\n\nclass FruitSerializer extends Serializer<Fruit> {\n  Map<String, dynamic> toJson(Fruit fruit) {\n    return ...;\n  }\n\n  Fruit fromJson(Map<String, dynamic> data) {\n    return Fruit(...);\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
someMethod<T>(Serializer<T> serializer, T value) {\n  ...\n}\n\nsomeMethod(FruitSerializer(), someFruit);\nfinal fruit = recreateFruit(FruitSerializer());\n
Run Code Online (Sandbox Code Playgroud)\n

显然,您不能将无法序列化的对象传递给代码,因为该方法需要一个Serializer<T>.

\n


lrn*_*lrn 6

恐怕无法按您想要的方式工作。

构造函数不是接口的一部分。他们的行为更像静态成员。因此,您不能在接口中添加工厂,并且给定类型变量来扩展该类型,代码将无法调用工厂构造函数。

因此,由于构造函数不能是接口的一部分,因此构造函数也不能是abstract。抽象只是意味着“使成员成为接口的一部分,但没有实现添加到类中”。

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

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

T deserialize<T extends JsonSerializable>(
    String json, T factory(Map<String, dynamic> data) {
   return factory(jsonParse(json) as Map<String, dynamic>);
}
Run Code Online (Sandbox Code Playgroud)