接口
接口(interface)即代码之间的契约。 本章节将结合示例讨论Dart中的隐式接口、接口类、纯接口等概念。
隐式接口
广义上一个library暴露一些成员(函数、类、字段、方法等)给另一个library使用,这些暴露的成员便组成了接口。Dart的普通类隐式地定义了一个接口。
// ex521.dart
class Vehicle {
void moveForward(double meters) {
print('moving forward $meters meters');
}
}
class Car implements Vehicle {
@override
void moveForward(double meters) {
// TODO: implement moveForward
}
}
此例中 Car 实现了 Vehicle , 因此它必须重写 moveForward(double) 方法,否则无法通过编译。Vehicle 隐式地定义了如下接口:
abstract interface class IVehicle {
void moveForward(double meters);
}
abstract interface class 表示纯接口,概念上与Java中的interface对应。
接口类
使用 interface class 创建一个接口类(或简称接口)。
// ex522.dart
interface class Vehicle {
void moveForward(double meters) {}
}
外部library中的类可以实现接口类,但不能继承接口类。
// ex523.dart
import './ex522.dart';
class Car implements Vehicle {
@override
void moveForward(double meters) {
// TODO: implement moveForward
}
}
// Error: The class 'Vehicle' can't be extended outside of its library
// because it's an interface class.
class Truck extends Vehicle {}
实现接口类,意味着要重写接口类定义的所有公开的实例方法。不能继承接口类,意味着无法通过 super关键字调用接口类定义的实例方法。接口类保证了:
- 实现类的某个实例方法A,通过
this关键字调用另一个实例方法B时,A与B始终位于同一个library中; - 实现类无法通过
super调用接口类中的实例方法,接口类里的实例方法的具体实现不直接影响实现类,这减少了脆弱基类问题(fragile base class problem)。
纯接口
纯接口即抽象接口类(abstract interface class),它的实例方法通常是抽象方法,即只有方法签名没有具体实现。
// ex524.dart
abstract interface class Vehicle {
void moveForward(double meters);
}
纯接口中的实例方法只能是抽象方法吗?答案是否定的。
abstract interface class Vehicle2 {
void moveForward(double meters);
void moveBackward(double meters) {
print('move backward $meters meters');
}
}