【问题标题】:Inheritance on Dart Null Safety for testability继承 Dart Null 安全性以实现可测试性
【发布时间】:2021-04-21 19:31:32
【问题描述】:

我有一个与 Dart Null Safety 概念相关的问题。

假设我有一个名为 Bird

的课程
class Bird{
Object character;

Bird();
}

鸽子

class Pigeon extends Bird{
String name;

Pigeon();
}

现在,由于 Dart 的 Null Safety,必须实例化角色对象。 我想在构造函数中实例化它,因为我希望鸟类可以使用 Mockito 进行测试。

但是,当我写这篇文章时

class Bird{
late Object character;

Bird(this.character);
}

Pigeon 类显示错误,因为 Bird 类没有任何零参数构造函数。

我的解决方法是使用这样的非必需参数。

class Bird{
late Object character;

Bird({Object? character}) : this.character= character ?? GetIt.I<Object>();;
}

但是,我不喜欢 GetIt 部分作为我的默认值。此外,其他程序员可能认为这是一个可选参数,因为我没有将其标记为 必需,这可能会导致错误。

那么,解决这种情况的最佳做法是什么?

【问题讨论】:

  • 对于Pigeon 实例,您希望character 是什么?为什么不让Pigeon 将适当的参数传递给Bird 构造函数?您似乎还误解了其他一些事情(例如,您不需要使用late,并且required 对于命名参数是必需的,以区分必需的命名参数和可选的命名参数)。跨度>
  • 不要使用late。这是一个非常糟糕的主意。尝试找到更好的解决方案。
  • @jamesdlin 角色对象只是一个例子。它可以包含鸟类的基本特征(例如鸟喙的类型)。此外,在非空变量中,如果您在构造函数中将“required”关键字声明为 namedArgs。
  • @mezoni 同意了。有什么想法吗?这就是我想在这里讨论的原因。
  • @DarariNurAmali 无论如何,我的意思是,我们无法就如何解决您的问题给出一个好的答案,因为在不知道您希望 characterPigeon 做什么的情况下,我们可以t真的告诉你应该如何初始化它。如果所有Pigeon 实例的初始值应该相同,那么Pigeon 构造函数应该只使用适当的参数调用Bird 构造函数。或者,如果它在 Pigeons 中有所不同,那么它可能也应该是 Pigeon 的构造函数的参数。

标签: flutter dart inheritance dart-null-safety


【解决方案1】:

您可以使用命名参数构造函数来使字符可选或像这样删除late?

class Bird{
  Object character;

  Bird(Object character) : this.character = character ?? GetIt.I<Object>();
}

您的命名参数构造函数将如下所示

class Bird{
  Object character;

  Bird({this.character = DEFAULT_CONST_VALUE});
}

【讨论】:

  • 对象字符是一个对象,要实例化需要 new Object() ,它不是常量。所以,这是不可能的。此外,非空变量应与 namedArgs 中的“required”关键字一起声明。
【解决方案2】:

这个解决方案怎么样?

class Bird {
  Object character;

  Bird({this.character});
}

class Pigeon extends Bird {
  String name;

  Pigeon({this.name, Object character}) : super(character: character);
}

甚至这个?

class Bird<T> {
  T character;

  Bird({this.character});
}

class Pigeon extends Bird<String> {
  String name;

  Pigeon({this.name, String character}) : super(character: character);
}

还是这个?

class Character {
  //
}

class Bird<T extends Character> {
  T character;

  Bird({this.character});
}

class Pigeon extends Bird<PigeonCharacter> {
  String name;

  Pigeon({this.name, PigeonCharacter character}) : super(character: character);
}

class PigeonCharacter extends Character {
  //
}

【讨论】:

  • 我们是否必须从父类声明所有非空值?
  • 三种方式。稍后声明和初始化它们时使用late 关键字。将它们声明为可为空的。将它们声明为不可为空并使用适当的值对其进行初始化。由您决定。
【解决方案3】:

你需要使用下面的命名构造函数

class Bird{
 Object character;
  
 Bird({this.character});
  
 Bird withCharater(Object character) {
   return Bird(character: character);
 }
}

class Pigeon extends Bird{
 String name;

 Pigeon(); 
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-20
    • 2012-07-28
    • 2021-09-12
    • 2010-09-29
    • 2021-08-05
    • 1970-01-01
    • 2012-08-01
    相关资源
    最近更新 更多