序言
类修饰符控制如何在类 或 mixin自己的库中 以及在定义类 或mixin的库外部使用类 或mixin。
修饰符关键字出现在类或mixin声明之前。例如,编写抽象类定义了一个抽象类。可以出现在类声明之前的修饰符的完整集合包括:

只有base 修饰符可以出现在mixin声明之前。这些修饰符不适用于其他声明,如enum、typedef、extension或 extension type。
在决定是否使用类修饰符时,请考虑类的预期用途以及类需要能够依赖的行为。
无修饰符
要允许从任何库构造或子类型的不受限制的权限,请使用不带修饰符的类或 mixin 声明。默认情况下,您可以:
・构造类的新实例。
・扩展类以创建新的子类型。
・实现类或 mixin 的接口。
・混合在混合或混合类中。
abstract
要定义一个不需要其整个接口的完整、具体实现的类,请使用abstract。
抽象类不能从任何库中构造,无论是自己的库还是外部库。
抽象类通常有抽象方法。
abstract class A {
var i = 0;
call() {
print('call');
}
void a();
}
extends A
class C extends A {
@override
void a() {
//必须重写
print('a');
}
}
和java不同的是,class的使用相当灵活,class 也可以被实现,需要回顾的同学参考这里Android学Dart学习笔记第十五节 类
implement A
class B implements A {
@override
get i => 0;
@override
set i(int value) => 0;
@override
void a() {
print('a');
}
@override
call() {
//必须重写
print('call');
}
}
如果你希望抽象类A看起来好像可以被直接实例化,可以使用工厂构造
abstract class A {
var i = 0;
**factory A() => C();**
call() {
print('call');
}
void a();
}
base
要强制继承类或 mixin 的实现,请使用 base 修饰符。基类不允许在其自己的库之外实现。这保证:
- 每当创建类的子类型的实例时,都会调用基类构造函数。
- 所有实现的私有成员都存在于子类型中。
- 基类中的新实现成员不会中断子类型,因为所有子类型都继承新成员。
除非子类型已经声明了具有相同名称和不兼容签名的成员,否则这是正确的。
您必须将任何实现或扩展基类的类标记为base, final, or sealed。
这可以防止外部库破坏基类保证。

在同一个dart文件中base 修饰的类可以被继承和实现,但必须使用base, final, or sealed

在另一个dart文件中,无法实现base修饰的类。
interface
同样,定义一个接口需要使用interface修饰。
接口自身定义所在的库之外的其他库可以实现该接口,但不能扩展它。这保证了:
・当类的某个实例方法调用该类上的另一个实例方法时,它总会调用来自同一库中该方法的已知实现。
・其他库无法以意想不到的方式重写接口类自身方法后续可能调用的方法。这减少了脆弱基类问题。

interface 修饰的类,可以被创建,可以在同一文件中被继承、实现,可以在外部文件中实现,但不能在外部文件中继承。
abstract interface
interface 修饰符最常见的用途是定义纯接口。
将 interface(接口)修饰符和 abstract(抽象)修饰符结合起来,用于抽象接口类。
与接口类类似,其他库可以实现抽象接口类,但不能继承抽象接口类。
与抽象类类似,抽象接口类可以包含抽象成员,但不能直接实例化。


final
和java中的区别很大,下面的话仔细看
要关闭类型层次结构,请使用 final 修饰符。这可以防止从当前库外部的类进行子类型化 。同时禁止继承和实现可以完全阻止子类型化。这保证了:
・您可以安全地向 API 添加增量更改。
・您可以调用实例方法,因为您知道它们没有在第三方子类中被重写。
最终类(final classes)可以在同一库中被扩展或实现 。
final 修饰符包含了 base 的作用,因此任何子类也必须标记为 base、final 或 sealed。

在同一个dart文件中,final类也可以被实现和继承,但必须使用 base final sealed 修饰

不可以被其他文件继承或者实现。
sealed
若要创建一个已知的、可枚举的子类型集合,请使用 sealed 修饰符。这使你能够基于这些子类型创建一个 switch 语句,并且该语句能被静态确保是穷举的。
sealed 修饰符防止类在其自身库外部被继承或实现。密封类(sealed classes)隐式为抽象类。
・它们自身不能被实例化。
・它们可以有工厂构造函数。
・它们可以为其子类定义可供使用的构造函数。
但是,密封类的子类不是隐式抽象的。
编译器知道任何可能的直接子类型,因为它们只能存在于同一个库中。这使得当 switch 语句的情况没有详尽地处理所有可能的子类型时,编译器能够向你发出警报。
下面先看sealed的定义和他的特性


外部文件不可以继承、实现、混合。
下面是使用场景

当你使用switch语句作用于sealed时,必须考虑他的所有可能,这是上面提到的穷举性,和枚举很相似。
如果你不希望进行详尽的switch,或者希望以后能够添加子类型而不破坏 API,请使用 final 修饰符。
Combining modifiers(组合修饰符)
你可以组合一些修饰符来实现分层限制。类声明的顺序可以是:
1.(可选)abstract(抽象的),用于描述该类是否可以包含抽象成员并阻止实例化。
2.(可选)base、interface、final 或 sealed 中的一个,用于描述其他库对该类进行子类型化时的限制。
3.(可选)mixin(混入),用于描述该声明是否可以被混入。
- 类关键字本身。
有些修饰符不能组合使用,因为它们相互矛盾、冗余或在其他方面互斥:
・abstract(抽象的)与 sealed(密封的)。密封类默认是抽象的。
・interface(接口)、final(最终的)或 sealed(密封的)与 mixin(混入)。这些访问修饰符会阻止混入。
有效的组合如下


下面是错误的组合
