一、继承

  • 子类使用 extends 关键词来继承父类。
  • 子类会继承父类里可见的属性和方法(包括getter和setter);但不会继承父类的构造函数。
    • super 可以调用父类的构造函数和方法。
  • 子类能复写父类的 方法、getter 和 setter。
    • 复写父类方法时:@override(末尾没有分号) 可写可不写,但是建议写上,方便阅读。
  1. // 父类
  2. class Rect {
  3. num width;
  4. num height;
  5. Rect(this.width, this.height);
  6. void set setheight(int value) {
  7. this.height = value;
  8. }
  9. num get area {
  10. return this.width * this.height;
  11. }
  12. }
  13. // 子类
  14. class Cube extends Rect {
  15. num deep;
  16. // NOTICE: width和height使用父类构造器初始化,而deep使用子类自己的构造器初始化。
  17. Cube(num width, num height, this.deep) : super(width, height);
  18. // Cube(num width, num height, this.deep) : super.xxx(width, height);
  19. @override
  20. num get area {
  21. return this.width * this.height * this.deep;
  22. }
  23. }
  24. void main() {
  25. Cube c1 = new Cube(3, 4, 5);
  26. print("体积:${c1.area}");
  27. }

mixins实现类似多继承 - with

在Dart中使用mixins实现类似多继承的功能。 条件一直在变花,以下是基于Dart2.x中使用mixins的条件:

  1. 作为mixins的类只能继承自Object,不能继承其他类:如A和B不能继承
  2. 作为mixins的类不能有构造函数:如A和B不能由构造器
  3. 一个类可以mixins多个mixins类:如C可以mixins类A和B
  4. mixins绝不是继承,也不是接口,而是一种全新的特性。当然你可以理解为 类似多继承.
  5. mixins的类型就是其超类的子类型
  1. class A {
  2. String aName = 'this is A';
  3. void printA()=> print(aName);
  4. }
  5. class B {
  6. String bName = 'this is B';
  7. void printB()=> print(bName);
  8. }
  9. // mixins A和B
  10. class C with A,B {}
  11. // class C extends A with B {} // 继承A;mixins B (A就没有mixins的约束)
  12. void main() {
  13. C c1 = new C();
  14. print("A: ${c1.aName} -- B: ${c1.bName}");
  15. print(c1 is A);// true
  16. print(c1 is B);// true
  17. print(c1 is C);// true
  18. }

二、抽象类

抽象类就只是制定了一个标准的模具,不能当成实际产品使用。— 定义标准

  1. 抽象类用 abstract 关键字声明
  2. 抽象类中:用abstract修饰的属性是抽象属性;没有方法体的方法是抽象方法。没有构造函数(因此不能实例化)
  3. 子类继承抽象类必须实现抽象类中的抽象方法;抽象类作为接口使用的时候必须实现所有的属性和方法。 — VS Code 快速修复… (Ctrl+.)

extends继承抽象类

复用抽象类的里的方法,并且要用抽象方法约束子类。

  1. abstract class Phone {
  2. void call();
  3. void playGame();
  4. }
  5. class Huawei extends Phone {
  6. String name;
  7. String processor;
  8. Huawei(this.name, this.processor);
  9. @override
  10. call() {
  11. // TODO: implement call
  12. throw UnimplementedError();
  13. }
  14. @override
  15. playGame() {
  16. // TODO: implement playGame
  17. throw UnimplementedError();
  18. }
  19. }
  20. void main() {
  21. Huawei h1 = new Huawei('huawei', '麒麟9000');
  22. print(h1.name);
  23. }

implements实现接口

把抽象类当做标准:属性和方法

  • 没有interface关键字定义接口;而是普通类或抽象类都可以作为接口被实现;使用implements关键字进行实现。
  • 实现:
    • 如果实现的是普通类:会将普通类和抽象类中的属性和方法全部复写;
    • 建议使用抽象类定义接口;
  1. abstract class DB {
  2. abstract String name;
  3. abstract String username;
  4. abstract String password;
  5. abstract String port;
  6. void add();
  7. void edit();
  8. }
  9. class MySQL implements DB {
  10. @override
  11. String name;
  12. @override
  13. String port;
  14. @override
  15. String username;
  16. @override
  17. String password;
  18. MySQL(this.name, this.port, this.username, this.password);
  19. @override
  20. void add() {
  21. // TODO: implement add
  22. }
  23. @override
  24. void edit() {
  25. // TODO: implement edit
  26. }
  27. }
  28. void main() {
  29. MySQL m1 = new MySQL('mysql', '3306', 'root', 'root');
  30. print(m1.name);
  31. }

implements实现多个接口

满足所有接口的要求即可

  1. abstract class DBData {
  2. abstract String name;
  3. abstract String username;
  4. abstract String password;
  5. abstract String port;
  6. }
  7. abstract class DBMethods {
  8. void add();
  9. void edit();
  10. }
  11. class MySQL implements DBData,DBMethods {
  12. @override
  13. String name;
  14. @override
  15. String port;
  16. @override
  17. String username;
  18. @override
  19. String password;
  20. MySQL(this.name, this.port, this.username, this.password);
  21. @override
  22. void add() {
  23. // TODO: implement add
  24. }
  25. @override
  26. void edit() {
  27. // TODO: implement edit
  28. }
  29. }
  30. void main() {
  31. MySQL m1 = new MySQL('mysql', '3306', 'root', 'root');
  32. print(m1.name);
  33. }