is 和 as 运算符
本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 60 课,共 110 课。
虽然 runtimeType 会告诉你确切的类型,但 Dart 提供了两个更实用的运算符,用于类型检查和类型转换:is 和 as。
is 运算符用于检查对象是否属于特定类型,并返回一个布尔值。与 runtimeType 不同,对于父类型,它也会返回 true:
class Animal {}
class Dog extends Animal {}
void main() {
Animal pet = Dog();
print(pet is Dog); // true
print(pet is Animal); // true(Dog 是一个 Animal)
print(pet is String); // false
}在 if 语句中使用 is 时,Dart 会自动进行类型提升,让你无需显式类型转换即可访问子类成员:
void handleAnimal(Animal animal) {
if (animal is Dog) {
// 在这里,Dart 知道 animal 是 Dog 类型
animal.bark(); // 可以调用 Dog 特有的方法
}
}as 运算符会将对象显式转换为特定类型。当你确定对象的类型时,可以使用它:
Animal pet = Dog();
Dog myDog = pet as Dog; // 转换为 Dog 类型
myDog.bark();使用 as 时要小心,如果类型转换失败,就会抛出异常。因此,与其直接使用 as,通常结合 is 和类型提升会更安全。你也可以使用 is! 来检查对象是否不是某种类型。
挑战
简单我们来构建一个形状处理系统,使用 is 和 as 运算符来识别和处理不同类型的形状。你将创建一个形状层次结构,并编写函数来检查类型和安全地访问特定类型的属性。
你将把代码分成两个文件:
shapes.dart:在这里定义形状层次结构:- 创建一个
Shape类,包含String name属性和构造函数。添加一个describe()方法,用来打印[name] is a shape - 创建一个继承自
Shape的Circle类,并添加double radius属性。添加一个getCircleInfo()方法,用来打印Circle with radius: [radius] - 创建一个继承自
Shape的Rectangle类,并添加double width和double height属性。添加一个getRectangleInfo()方法,用来打印Rectangle: [width] x [height]
- 创建一个
main.dart:导入形状文件,并创建一个processShape(Shape shape)函数,该函数需要:- 首先对形状调用
describe() - 使用
is检查形状是否为Circle。如果是,则使用类型提升调用getCircleInfo() - 使用
is检查形状是否为Rectangle。如果是,则使用as运算符进行类型转换并调用getRectangleInfo() - 使用
is!检查形状是否既不是Circle,也不是Rectangle。如果是,则打印Unknown shape type
main()函数中:- 创建一个名为
'Round'、半径为5.0的Circle,并将它传给processShape() - 打印一个空行
- 创建一个名为
'Box'、宽度为4.0、高度为3.0的Rectangle,并将它传给processShape() - 打印一个空行
- 创建一个名为
'Mystery'的基础Shape,并将它传给processShape()
- 首先对形状调用
这个挑战展示了两种方法:对 Circle 使用 is 和自动类型提升,以及对 Rectangle 使用 as 进行显式类型转换。你还将看到 is! 如何帮助识别不属于任何特定子类型的形状。
预期输出:
Round is a shape
Circle with radius: 5.0
Box is a shape
Rectangle: 4.0 x 3.0
Mystery is a shape
Unknown shape type亲手试试
import 'shapes.dart';
// TODO:创建函数 processShape(Shape shape),使其:
// 1. 首先调用该形状的 describe()
// 2. 用 'is' 检查 shape 是否为 Circle;如果是,就通过类型提升调用 getCircleInfo()
// 3. 用 'is' 检查 shape 是否为 Rectangle;如果是,就用 'as' 运算符进行类型转换并调用 getRectangleInfo()
// 4. 用 'is!' 检查 shape 既不是 Circle 也不是 Rectangle;如果是,就打印 "Unknown shape type"
void main() {
// TODO:创建一个名为 'Round'、半径为 5.0 的 Circle,并将其传给 processShape()
// TODO:打印一个空行
// TODO:创建一个名为 'Box'、宽为 4.0、高为 3.0 的 Rectangle,并将其传给 processShape()
// TODO:打印一个空行
// TODO:创建一个名为 'Mystery' 的基础 Shape,并将其传给 processShape()
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器