首页 > 解决方案 > 在 Dart 中覆盖类字段的最佳实践

问题描述

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

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

  late Color primaryColor;
  late Color iconColor;
}

(我必须将它们定义为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;
}

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

BaseTheme _lightTheme = new LightTheme();

ThemeData _theme = ThemeData(
  scaffoldBackgroundColor: _lightTheme.backgroundColor,
  // etc...
}

现在,这似乎工作正常。但是,Linter for Dart 中有关覆盖字段的页面指出,覆盖字段是不好的做法。那么,有没有更好的方法来实现类似的目标?

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

任何指针(没有双关语)都是最受欢迎的!

标签: flutterdart

解决方案


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

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

  Color get appBarBackgroundColor;
  set appBarBackgroundColor(Color value);

  // etc.
}

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

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

  // etc.
}

另请参阅 GitHub 问题:overridden_​​fields 文档是 vague


推荐阅读