文章

抽象类_多态和接口

抽象类/多态和接口

抽象类_多态和接口

抽象类/多态和接口

抽象类

Dart抽象类主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口。

  1. 抽象类通过 **abstract** 关键字来定义;
  2. Dart 中的抽象方法不能用abstract声明,Dart 中**没有方法体的方法我们称为抽象方法**;
  3. 如果子类继承抽象类必须得实现里面的抽象方法;
  4. 如果把抽象类当作接口实现的话必须得实现抽象类里面定义的所有属性和方法;
  5. 抽象类不能被实例化,只有继承它的子类可以;

extends抽象类 和 implements 的区别:

  1. 如果要复用抽象类里面的方法,并且要用抽象方法约束子类的话我们就要用extends继承抽象类;
  2. 如果只是把抽象类当作标准的话我们就用implements实现抽象类;

案例:定义一个 Person 类要求它的子类必须包含 eat 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 抽象类通过 abstract 关键字来定义
abstract class Person {
  // 抽象方法 - 没有方法体的方法我们称为抽象方法
  eat();
  run();

  // 非抽象方法
  getInfo() {
    print('我是抽象类里面的普通方法');
  }
}

class Man extends Person {
  // 如果子类继承抽象类必须得实现里面的抽象方法
  @override
  eat() {
    print('man eat');
  }

  @override
  run() {
    print('man run');
  }
}

main() {
  Man m = new Man();
  m.eat(); // man eat
  m.run(); // man run
  m.getInfo(); // 我是抽象类里面的普通方法

  // 报错 - 抽象类没法直接被实例话
  Person p = new Person();
}

多态

定义:允许子类类型的指针赋值给父类的指针,同一个函数调用会有不同的执行效果;

子类的实例赋值给父类的应用;

理解:多态就是父类定义一个方法不去实现,让继承它的子类去实现,每个子类有不同的表现;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 抽象类通过 abstract 关键字来定义
abstract class Person {
  // 抽象方法 - 没有方法体的方法我们称为抽象方法
  eat();
}	

class Man extends Person {
  // 如果子类继承抽象类必须得实现里面的抽象方法
  @override
  eat() {
    print('man eat');
  }

  run() {
    print('run');
  }
}

class WoMan extends Person {
  @override
  eat() {
    print('woman eat');
  }

  run() {
    print('run');
  }
}

main() {
  Person m = new Man();
  m.eat(); // man eat
  // 报错
  m.run(); // The method 'run' isn't defined for the type 'Person'

  Person w = new WoMan();
  w.eat(); // woman eat
  // 报错
  w.run(); // The method 'run' isn't defined for the type 'Person'
}

接口

Dart的接口没有 interface 关键字,而是普通类或抽象类都可以作为接口被实现;

同样适用 implements 关键字进行实现。

但是 dart 的接口有点奇怪,如果实现的类是普通类,会将普通类和抽象类中的属性和方法全部需要复写一遍;

而因为抽象类可以定义抽象方法,普通类不可以,所以一般如果要实现像Java接口那样的方式,一般会使用抽象类;

建议使用抽象类定义接口。

示例:定一个DB库支持 mysql mssql mongodb

mysql mssql mongodb 三个类里面都有同样的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Db抽象类 当作接口 接口就是约定/规范
abstract class Db {
  String uri = ''; // 数据库的连接地址
  add(String data);
  save();
  delete();
}

class Mysql implements Db {
  @override
  String uri;

  Mysql(this.uri);

  @override
  add(String data) {
    print('Mysql add ${data}');
  }

  @override
  save() {

  }

  @override
  delete() {

  }

  // 扩展的方法
  remove() {
    
  }
}

class MsSql implements Db {
  @override
  String uri;

  MsSql(this.uri);

  @override
  add(String data) {
    print('MsSql add ${data}');
  }

  @override
  save() {

  }

  @override
  delete() {

  }
}

main() {
  Mysql mysql = new Mysql('xxxxx');
  mysql.add('123');
}
本文由作者按照 CC BY 4.0 进行授权