首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在使用Freezed时编写抽象类

在使用Freezed时编写抽象类
EN

Stack Overflow用户
提问于 2022-10-26 18:01:22
回答 2查看 85关注 0票数 0

我似乎无法理解如何使抽象类及其子类与Freezed一起正常工作。具体来说,我需要定义一个带有一些要重写getter的抽象超类;子类需要覆盖getter,同时利用冻结来生成它们的样板代码。

我确实理解文档的意思,但我确实需要更多。

我创建回购是为了展示我所需要的,以防你想切入追逐。我所需要的只是这些测试按预期传递和工作。

我需要一种干净、可读和可维护的方法来完成这个任务。

场景

在回购过程中,你会发现一个小的复制案例:

  • 一个Base抽象类;
  • 一个类A,它扩展了Base类(我想简化事情,但是在我的实际用例中确实有更多的子类,比如XYZ等等);
  • A需要用Freezed序列化/反序列化来实现;

回顾:BaseAXYZ之间有共同之处;正如上面提到的,对于这些子类来说,Freezed是必需的。

目标

我的目标是利用构图。

让一个类B有一个Base get myValue getter,并使用Freezed。不足为奇的是,我希望通过访问它的copyWith方法(或其他方法,如toJson)来与该值交互,但这变得非常复杂(参见问题1)。

同样,阅读测试以获得所需的结果。

问题1

实现上面所描述的,虽然这是有意义的,但这不是一件容易的事情(对我的理解)。

例如,以下内容:

代码语言:javascript
复制
abstract class Base {
  const Base();

  Function copyWith();
  Map<String, dynamic> toJson();

  String get id;
}

无法工作,因为子类在要使用的超类方法(错误这里)上会感到模糊:它是使用由@freezed生成的方法还是使用抽象的方法?这是编译时的错误。

我不知道如何正确地写一份合同,同时利用冻结。

问题2

首先,build_runner理所当然地抱怨,因为它不能将fromJson方法生成到B上,因为Base没有@JsonSerializable方法。

这将意味着手动实现转换器:我这样做了,但这很快就过时了。这意味着为创建的每个新子类重写转换器,并为尚未处理的子类引发异常(这是一种强烈的代码气味)。

这个文件中发现了这样的暴行。

如何才能以干净的方式实现这一目标?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-28 18:08:06

经过两天的工作和研究,我终于摆脱了困境。

  1. 我现在不得不放弃freezed (我只为联盟型系统保留它);
  2. 显然,用手实现这一目标是不可能的;
  3. 我使用了这个包:可映射,这完全符合我前面的要求。

我将在这里发布一个用dart_mappable可以实现的快速伪代码实现

代码语言:javascript
复制
@MappableClass()
abstract class MyBase with MyBaseMappable {
  const MyBase(this.id);
  final String id;
}

@MappableClass()
class A extends MyBase with AMappable {
  const A(super.id);
}

@MappableClass()
class B with BMappable {
  const B(this.value);
  final MyBase value;
}


void main() {
  const a = A('hello');
  const b = B(a);
  print(b.value.copyWith(id: "lol"));  // Yes!
}

这要求v2 of dart_mappable工作,目前处于预发布状态。

票数 0
EN

Stack Overflow用户

发布于 2022-10-27 09:15:44

您的问题可能源于Base定义了一个空的copyWith

冻结不将copyWith作为方法实现,而是作为返回函数(或可调用对象)的getter实现。这对于copyWith(foo: null)支持是必要的,但与您的接口不兼容。

扩展Base也可能是一个问题。由于语言的限制,冻结不能很好地支持继承。您可能更好地实现Base或使它成为一个混合体。

总之,你可以:

代码语言:javascript
复制
mixin Base {
  int get id;

  Map<String, dynamic> toJson();
}

@freezed
class A with _$A, Base {
  const A._();

  factory A({
    required int id;
  }) = _A;
  
  factory A.fromJson(Map<String, dynamic> json) => _$AFromJson(json);

  @override
  Map<String, dynamic> toJson() => _$AToJson(this);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74212270

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档