Dart 中重写类字段的最佳实践

Tar*_*eem 6 dart flutter

我正在为我的应用程序创建一个主题系统,我希望创建一个基本主题类,其中包含颜色和字体字段:

abstract class BaseTheme {
  late Color backgroundColor;
  late Color appBarBackgroundColor;
  late Color progressIndicatorColor;

  late Color primaryColor;
  late Color iconColor;
}
Run Code Online (Sandbox Code Playgroud)

(我必须将它们定义为late让 Null Safety 满意!无论如何,这些都必须被覆盖,所以没有问题)。

然后我将为implement每个主题建立这个基类,如下所示:

import 'base_theme.dart';

class LightTheme implements BaseTheme {
  Color backgroundColor = Colors.white;
  Color appBarBackgroundColor = Color(0xff1a1818);
  Color progressIndicatorColor = Color(0xffffc114);

  Color primaryColor = Colors.red;
  Color iconColor = Colors.white;
}
Run Code Online (Sandbox Code Playgroud)

然后我将使用这些值来填充ThemeData

BaseTheme _lightTheme = new LightTheme();

ThemeData _theme = ThemeData(
  scaffoldBackgroundColor: _lightTheme.backgroundColor,
  // etc...
}
Run Code Online (Sandbox Code Playgroud)

现在,这似乎运作良好。然而, Dart 的 Linter 中关于重写字段的页面指出,重写字段是不好的做法。那么,有没有更好的方法来实现类似的目标呢?

令人困惑的是,在该页面上,一个示例显示了当您extend使用基类时覆盖字段,这被认为是不好的。但是,当您implement是基类时覆盖字段是好的 - 但在这种情况下,字段类型已从 更改为BaseDerived(即它们不一样)。

jam*_*lin 8

正如 lint 建议的那样,您应该避免覆盖字段。你的抽象类应该定义一个接口;因此,它应该声明gettersetter,并将实现留给具体的派生类。请注意,这避免了需要late(这是不属于抽象基类的实现细节)。

abstract class BaseTheme {
  Color get backgroundColor;
  set backgroundColor(Color value);

  Color get appBarBackgroundColor;
  set appBarBackgroundColor(Color value);

  // etc.
}
Run Code Online (Sandbox Code Playgroud)

Dart 2.13 允许将成员声明为abstract,因此您可以使用它来避免重复:

abstract class BaseTheme {
  abstract Color backgroundColor;
  abstract Color appBarBackgroundColor;

  // etc.
}
Run Code Online (Sandbox Code Playgroud)

另请参阅 GitHub 问题:overridden_​​fields 文档含糊不清