1、extends(继承):
- 含义:
在Dart中,extends关键字用于创建一个类的子类,子类将继承父类的属性和方法。子类可以通过扩展来添加新的功能或通过重写方法来定制化父类的行为。
- 使用场景:
常用于建立类的继承关系,当子类与父类之间具有明显的 is-a 关系时,使用继承是很自然的。
- 特性:
子类继承了父类的所有公共属性和方法,可以访问并使用它们。子类可以通过重写父类的方法来实现多态性。
scala
// 父类
class Animal {
void makeSound() {
print('Animal - makeSound');
}
}
// 子类
class Dog extends Animal {
// 子类重写父类的方法
@override
void makeSound() {
print('Dog - makeSound');
}
}
// 子类
class Cat extends Animal {}
void main() {
Dog dog = Dog();
Cat cat = Dog();
dog.makeSound(); // Output: Dog - makeSound
cat.makeSound(); // Output: Animal - makeSound
}
2、with(混入):
- 含义:
在Dart中,with关键字用于将一个或多个 mixin 类的功能混入到一个类中。Mixin 是一种特殊的多重继承,允许在不继承类的情况下重用代码。
- 使用场景:
常用于将通用功能添加到类中,而不是通过继承来实现。当一个类需要具有多个不相关的特性时,使用 mixin 是很有用的。
- 特性:
通过混入,类可以获得 mixin 类中定义的所有属性和方法,而不是继承它们。
scala
// Mixin类
mixin Swimming {
void swim() {
print('Swimming...');
}
}
// Mixin类
mixin Eating {
void eat() {
print('Eating...');
}
}
// Mixin类
mixin Drinking {
void drink();
}
// 子类混入多个Mixin
class Duck extends Animal with Swimming, Eating, Drinking {
// 某个Mixin中存在声明未实现的方法,子类必须通过重写去实现
@override
void drink(){
print('Duck - Drinking')
}
}
void main() {
Duck duck = Duck();
duck.makeSound(); // Output: Animal - makeSound
duck.swim(); // Output: Swimming...
duck.eat(); // Output: Eating...
duck.drink(); // Output: Drinking...
}
3、abstract(抽象):
- 含义:
在Dart中,abstract关键字用于定义一个抽象类,抽象类不能被实例化,通常包含一些抽象方法。抽象方法在抽象类中没有具体的实现,而是由子类来实现。
- 使用场景:
当一个类只是用于被其他类继承时,或者类中有一些方法需要子类来实现时,可以使用抽象类。
- 特性:
抽象类不能直接实例化,只能被用作其他类的父类。子类必须实现抽象类中的所有抽象方法,除非子类自己也是抽象类。
scala
// 抽象类父类
// 一般抽出结构不实现,给子类们以约束
// 未实现的成员在子类中就必须实现了
abstract class Shape {
Color getColor();
void draw();
}
// 子类
class Circle extends Shape {
@override
Color getColor => Colors.red;
@override
void draw() {
print('Drawing circle');
}
}
// 子类
class Rect extends Shape {
@override
Color getColor => Colors.blue;
@override
void draw() {
print('Drawing rect');
}
}
void main() {
Circle circle = Circle();
circle.draw(); // Output: Drawing circle
}
4、interface(接口) 和 implements(实现)
-
含义:
-
interface
- 在Dart中,虽然没有显式的 interface 关键字,但是class类可以充当接口
- 接口定义了一组要被实现的方法,但没有具体的实现。
-
implements
- 其他类可以通过 implements 关键字来实现这些接口
-
-
使用场景:
常用于定义一个类应该实现哪些方法的约定。通过实现接口,可以确保类具有特定的行为。
- 特性:
一个类可以实现多个接口,这使得 Dart 支持多重继承的部分特性。
typescript
// 抽象类(根据以上描述,那么这个class类也是接口)
abstract class Shape {
void draw();
}
class Circle implements Shape {
@override
void draw() {
print('Drawing circle');
}
}
class Rectangle implements Shape {
@override
void draw() {
print('Drawing rectangle');
}
}
void main() {
var circle = Circle();
var rectangle = Rectangle();
circle.draw(); // Output: Drawing circle
rectangle.draw(); // Output: Drawing rectangle
}
再区分 extends mixin implements:
-
extends
- 示例:class Child extends Parent {}
- 只能继承自一个父类
- 父类的方法被子类继承,如果方法没有实现,子类必须实现
-
mixin
- 示例:class Child with MixinParentA, MixinParentB {}
- 可以混入多个Mixin类
- 父类的方法被子类继承,如果方法没有实现,子类必须实现
-
implements
- 示例:class Child implements InterfaceParentA, InterfaceParentB {}
- 可以实现多个接口父类
- 父类的方法通常约定为不实现的方法
- 可无论父类的方法实现与否,子类都必须进行全量成员的重写实现