我正在为我的应用程序创建一个主题系统,我希望创建一个基本主题类,其中包含颜色和字体字段:
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是基类时覆盖字段是好的 - 但在这种情况下,字段类型已从 更改为Base到Derived(即它们不一样)。
正如 lint 建议的那样,您应该避免覆盖字段。你的抽象类应该定义一个接口;因此,它应该声明getter和setter,并将实现留给具体的派生类。请注意,这避免了需要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 文档含糊不清。