1、extends(承继):

  • 意义:

在Dart中,extends关键字用于创立一个类的子类,子类将承继父类的特点和办法。子类能够经过扩展来添加新的功用或经过重写办法来定制化父类的行为。

  • 运用场景:

常用于建立类的承继联系,当子类与父类之间具有明显的 is-a 联系时,运用承继是很自然的。

  • 特性:

子类承继了父类的一切公共特点和办法,能够拜访并运用它们。子类能够经过重写父类的办法来完成多态性。

// 父类
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 类中界说的一切特点和办法,而不是承继它们。

// 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关键字用于界说一个笼统类,笼统类不能被实例化,通常包含一些笼统办法。笼统办法在笼统类中没有详细的完成,而是由子类来完成。

  • 运用场景:

当一个类只是用于被其他类承继时,或许类中有一些办法需求子类来完成时,能够运用笼统类。

  • 特性:

笼统类不能直接实例化,只能被用作其他类的父类。子类有必要完成笼统类中的一切笼统办法,除非子类自己也是笼统类

// 笼统类父类
// 一般抽出结构不完成,给子类们以约束
// 未完成的成员在子类中就有必要完成了
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 支持多重承继的部分特性。

// 笼统类(依据以上描述,那么这个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 {}
    • 能够完成多个接口父类
    • 父类的办法通常约好为不完成的办法
    • 不管父类的办法完成与否,子类都有必要进行全量成员的重写完成