sealed基础使用
在Dart中,使用sealed关键字可以创建封闭类(sealed class)。封闭类只能在同一个库文件中被继承。例如:
dart
sealed class Animal {
void makeNoise() => print('Unknown animal noise!');
}
class Dog extends Animal {
void makeNoise() => print('Bark!');
}
class Cat extends Animal {
void makeNoise() => print('Meow!');
}
这里,Animal是一个封闭类(sealed class)。只有在同一个文件中,Dog和Cat类才能继承它。如果我们在其他文件中尝试继承Animal,会报错:
dart
class Fox extends Animal { // Error: Cannot extend sealed class 'Animal'
}
封闭类的主要目的有:
- 限制继承范围。只有在同一个库中我们才能继承该类,这使得该类的子类型数量是可知的,更易于管理。
- 实现完备性检查。因为我们知道所有的子类,所以可以在父类中为每个子类实现相应的方法和属性,并在编译时检查是否完成全部实现。这可以提高代码健壮性。
- 方便语句匹配。因为子类数量是确定的,我们可以在父类中使用switch语句根据子类类型执行相应逻辑,这在其他语言中不太方便。例如:
dart
void makeAnimalNoise(Animal animal) {
switch (animal.runtimeType) {
case Dog:
animal.makeNoise();
break;
case Cat:
animal.makeNoise();
break;
}
}
这里,因为Animal的子类只有Dog和Cat,所以我们可以使用switch根据子类型执行相应方法。总之,封闭类是Dart中一种限制继承与实现完备性检查的语言结构。熟练掌握它有助于我们开发出更加健壮的Dart程序。所以封闭类的特性和用法也值得我们在学习Dart的过程中进行深入理解与实践。每次定义一个继承体系时,我们也可以考虑是否适合使用封闭类,并实践一下。这无疑可以加深我们对其的理解,也可以锻炼我们在设计API和类结构上的能力。任何技术,都需要理论与实践相结合,才能运用自如。Dart的各种语言结构和特性也不例外,需要我们通过学习与实践来熟练掌握。
封闭类(sealed class)是隐式抽象的,不能被直接实例化。
例如,如果我们定义一个封闭类:
dart
sealed class Animal {}
然后尝试实例化它:
dart
var a = Animal(); // Error: Cannot instantiate abstract class 'Animal'
会报错,不能实例化抽象类Animal。这是因为封闭类隐式地被视为抽象类。尽管我们没有使用abstract关键字,但是Dart会自动将其视为抽象类,因为:1. 它不能被外部继承,只能在同一库中继承
2. 其子类型是已知且固定的所以,封闭类本质上是一种抽象类,只是语法上看似普通类。这使得它具有抽象类的一些特点:1. 不能被实例化,必须由子类实例化
2. 可以有抽象方法,要求子类实现
3. 可以实现完备性检查,确保子类实现了所有必要方法例如:
dart
sealed abstract class Animal {
void makeNoise(); // 抽象方法
}
class Dog extends Animal {
void makeNoise() => print('Bark!');
}
class Cat extends Animal {
void makeNoise() => print('Meow!');
}
这里,Animal是一个封闭抽象类,不能被实例化。它有一个抽象方法makeNoise(),要求子类Dog和Cat实现。这样可以确保所有子类都实现了该方法。所以,封闭类具有抽象类的这些特点,可以看作是一种隐式抽象类。由于它限定了子类型,所以在设计类继承体系时,使用封闭类可以实现更严密的完备性检查。这也是它的主要优点之一。理解封闭类的这一本质,可以让我们在Dart开发中更加灵活和高效地应用它。每次定义一个继承关系时,我们就可以考虑是否使用封闭类,并思考如何充分利用它的这一特点。这也是我们熟练掌握Dart语言的一个方面。所以,总结一下,封闭类有以下特征:- 隐式抽象,不能实例化
- 可以有抽象方法
- 可以实现完备性检查
- 子类型是确定的希望通过这些总结,可以让大家对Dart封闭类有一个更深入的理解。要真正掌握它,还是需要在实践中不断运用与体会。这也是我们学习Dart与提高技能的过程中必不可少的一步。理论与实践,两者缺一不可。封闭类的学习也同样需要我们按这个法则来进行。
封闭类(sealed class)在Dart中还有一些其他用法和语法细节:
- 可以继承Object类:
dart
sealed class Animal extends Object {
// ...
}
封闭类可以继承Object类,因为Object是Dart中所有类的父类。2. 可以实现接口:
dart
sealed class Animal implements NoiseMaker {
void makeNoise() => ...
}
封闭类可以实现接口,这在需要让子类实现某些方法时很有用。3. 可以有抽象方法:
dart
abstract sealed class Animal {
void makeNoise();
}
封闭类可以是抽象类,要求子类实现某些抽象方法。这可以实现完备性检查,确保所有子类都实现了所需方法。
- 子类可以在任何文件中:尽管只能在同一个库中继承封闭类,但是其子类可以定义在任意文件中。例如:animal.dart:
dart
sealed class Animal {}
dog.dart:
dart
class Dog extends Animal {}
cat.dart:
dart
class Cat extends Animal {}
这里Dog和Cat类在不同文件中,但是因为在同一个库中,所以可以继承Animal类。5. 可以扩展已有类:我们可以在已有类上添加sealed关键字,使其成为封闭类。例如:
dart
class Animal {
...
}
sealed class Animal extends Object {
...
}
现在Animal成为一个封闭类,只允许在同一库中继承。原来的Animal子类依然有效。所以,总结一下封闭类的其他细节:
- 可以继承Object类和实现接口
- 可以是抽象类
- 子类可以在任意文件中,只要在同一库
- 可以通过扩展已有类使其成为封闭类
这些特性使得封闭类在Dart中更加灵活使用。要真正掌握它,仍然需要我们在学习与实践中不断体会与总结。
每次使用封闭类,我们可以尝试不同的方式,如继承Object类,实现接口,在不同文件中定义子类等,来加深对其的理解。这也是我们学习Dart与成长为Dart高手的过程中必不可少的一部分。
理论和实践相结合,这是我们学习任何技能的基本法则。Dart的各种语言结构也需要我们用这种方式去理解与熟练掌握。封闭类作为Dart的一项重要特性,自然也不例外。