在 dart 3.0.0 之后,对类型的修饰符进行了拓展,现在类型的修饰符有:
名称 | 作用 |
---|---|
mixin | 混入类修饰符 |
sealed | 密封可枚举的子类型 |
abstract | 抽象类修饰符 |
final | 一定程度上关闭派生能力 |
base | 基 |
interface | 接口 |
在 dart 3.0.0 之前, 没有构造方法的 class 可以视为 mixin , 下面的代码是允许的:
class A {}
class C with A {}
在 dart 3.0.0 之后, mixin 变严格了,和 class 声明的常规类进行的区分,常规类将不被允许混入:
想要通过 with 关键字混入 A,需要通过 mixin 声明类:
mixin A {}
class C with A {}
或者通过 mixin 关键字对 class 进行修饰:
mixin class A {}
class C with A {}
也就是说,现在 Dart 中将 混入类 和 常规类 进行了语法级别的区分:
mixin 声明定义了一个混入类,允许被通过 with 混入或 on 继承。 class 声明定义了一个常规类,允许被通过 extends 继承。 mixin class 声明定义了一个既可用作常规类又可用作混入类的类。即允许被通过 with 混入或 on 继承,又允许被通过 extends 继承。
常规类
才允许使用 extends
或 with
子句,混入类不允许使用;混入类
才允许使用 on
子句,常规类不允许使用。 mixin class
含有两者的血脉,所以即无法使用 extends
或 with
子句,也无法使用 on
子句。有些类型的子类型集是已知的,可枚举的;比如登陆界面的认证状态 AuthState
,有如下三种子状态
这时就可以通过密封类来处理,下面的代码看起来似乎和平台的继承也没什么区别,但密封类有它的特点。
sealed class AuthState{} //创建密封类
class AuthLoading extends AuthState{}
class AuthSuccess extends AuthState{
final String user;
final String token;
AuthSuccess(this.user, this.token);
}
class AuthFailure extends AuthState{
final String error;
AuthFailure(this.error);
}
AuthState
的不同状态,返回不同的字符串。在实际开发中可以返回不同的组件,在对应的分支中可以访问对应派生类中的字段。比如 AuthSuccess 分支中可以通过 state.user
访问用户名;AuthFailure 分支中可以通过 state.error
访问错误信息:String buildByAuthState(AuthState state){
return switch(state){
AuthLoading()=> 'AuthLoading View',
AuthSuccess()=> 'AuthSuccess View:${state.user}',
AuthFailure()=> 'AuthFailure View:${state.error}',
};
}
sealed 最大的特点是子类型可枚举,所以在编码过程中如果少写一个,编译器就是显示地给出提示。这样可以有效避免漏写的可能,这种从语法层面规避潜藏风险,对代码的健壮性是非常友好的。
final 对类进行修饰,其目的是为了关闭该类的继承体系。如下所示,被 final 修饰的类无法被直接继承;
从提示中可以看出需要继承自 final 修饰的类,子类需要被 base 、final 或 sealed 修饰:
另外 final 修饰的类无法在外部进行派生:
从这两点就不难理解,final 修饰的类可以在一定程度上关闭派生能力。
base 和 interface 在我看来是一对,base 是强调 继承
; interface 是强调 实现
。两者的的目的是:
限制外部文件对修饰类的派生和实现。
base 修饰的类在外部 允许继承,不允许实现
interface 修饰的类在外部 不允许继承,允许实现
俗话说无规矩不成方圆,修饰符就是限制的规则,而接受限制就会享有更长远的利益。比如接受红绿灯的限制,会让整体的交通更加顺畅,减少拥堵,出事的可能性。而不是纠结于我多等了几十秒,不利于一时的享受。限制这是一种大局观,其目的是让整体更加有序。
类型修饰符的增加,可以让类本身多了一些特点,也可以控制类的派生能力,这对于构建大型应用来说是友好的。Kotlin 一直都有 sealed 密封类,这是让我垂涎的语法特性,现在 Dart 终于支持了。