Hellom's Studio.

Dart 学习之面向对象编程 2

字数统计: 1.2k阅读时长: 5 min
2019/07/16 Share

继承

  • 使用关键字 extends 继承一个类

  • 子类会继承父类可见的属性和方法 不会继承构造方法

  • 子类能够复写父类的方法、 gettersetter

  • 单继承 多态性

@override 表示覆写了父类里的方法

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
e.g.

//person.dart
class Person {
String name;
int age;

bool get isAdult => age > 18;

String run() {
return 'Name is $name , age is $age';
}
}

//class_extends.dart
import 'package:my_flutter/person.dart';

void main() {
var person = new Student();

person.age = 20;

person.name = 'Tom';

print(person.isAdult);

person.study();

print(person.run());
}

class Student extends Person {
void study() {
print('study...');
}

//覆写父类里面的方法
@override
bool get isAdult => age > 15;
}

继承中的构造方法

  • 子类的构造方法会默认调用父类的无名无参构造方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
e.g.

void main() {
var student = new Student();

print(student);
}

class Person {
String name;
int age;

//子类会默认调用
Person(){
print('这就是无名无参的构造方法');
}
}

class Student extends Person {
void study() {
print('study...');
}
}
  • 如果父类没有无名无参构造方法,则需要显示调用父类构造方法

  • 在构造方法参数后使用 : 显示调用父类构造方法

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
e.g.

void main() {
var student = new Student('Tom');

print(student.name);
}

class Person {
String name;
int age;

Person(this.name); // 无名有参构造方法

Person.withName(this.name); // 有名有参构造方法
}

class Student extends Person {
//调用父类的构造方法
Student(String name) : super(name);

void study() {
print('study...');
}
}

构造方法的执行顺序

  • 父类的构造方法会在子类构造方法开始之前执行的位置调用(同初始列表)

  • 如果有初始化列表,则初始化列表会在父类构造方法之前执行

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
e.g.

void main() {
var student = new Student('Tom','Male');

print(student.name);
print(student.gender);
}

class Person {
String name;
int age;

Person(this.name);

Person.withName(this.name);
}

class Student extends Person {
final gender;

//gender = g 是初始化列表 所以在父类构造方法之前执行
Student(String name, String g) : gender = g, super(name);

void study() {
print('study...');
}
}

抽象类

  • 抽象类使用关键字 abstract 来表示 不能直接被实例化

  • 抽象方法不用 abstract 修饰 无实现

  • 抽象类可以没有抽象方法

  • 有抽象方法的类一定得声明为抽象类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
e.g.

void main() {
var student = new Student();
student.run();
}

//抽象类
abstract class Person {
void run();
}

//继承这个抽象类
class Student extends Person {
//继承抽象类 要实现抽象方法
@override
void run() {
print('run....');
}
}

接口

  • 类和接口是统一的 类就是接口

  • 每个类都隐式的定义一个包含所有实例成员的接口

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
e.g.

void main() {
var student = new Student();
student.run();
}

class Person {
String name;
int age;

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

class Student implements Person{
@override
int age;

@override
String name;

@override
void run() {
// TODO: implement run
}

}
  • 如果是复用已有类的实现,使用继承(extends

  • 如果只是使用已有类的外在行为,使用接口(implements

建议使用抽象类的形式来作为接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
e.g.

void main() {
var student = new Student();
student.run();
}

abstract class Person {
void run();
}

class Student implements Person{
@override
void run() {
print('student run...');
}

}

Mixins

  • Mixins 类似于多继承,是在多类继承中重用一个类代码的方式

以下为 D 同时继承 A B C 类的栗子

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
e.g.

void main() {
var d = new D();
d.a(); // A.a()...
}

class A {
void a() {
print('A.a()...');
}
}

class B {
void b() {
print('B.b()...');
}
}

class C {
void c() {
print('C.c()...');
}
}

//先继承才能使用 Mixins 使用 with 连接
class D extends A with B, C {}
  • 作为 Minin 的类不能有显示声明构造方法

  • 作为 Minin 的类只能继承自Object(作为 Minin 的类不能被继承)

  • 使用关键字 with 连接一个或多个 mixin

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
e.g.

//发动机抽象类
abstract class Engine {
void work();
}

//烧油发动机
class OilEngine implements Engine {
@override
void work() {
print('work with oil...');
}
}

//电类发动机
class ElectricEngine implements Engine {
@override
void work() {
print('work with electric...');
}
}

//轮胎
class Tyre {
String name;

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

//简写方法
class Car = Tyre with OilEngine;

// 完整写法 更像是类的组装
class Cars extends Tyre with OilEngine{

}

class Bus = Tyre with ElectricEngine;

操作符覆写

  • 覆写操作符需要在类中定义

  • 如果覆写 == ,还需要覆写对象的 hashCode getter方法

可覆写的操作符参考官网提供:

https://dart.dev/guides/language/language-tour#overridable-operators

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
e.g.

void main() {
var person1 = new Person(20);
var person2 = new Person(22);

print(person1 > person2); // false 比较大小
print(person1['age']); // 20 使用[]取值
}

class Person {
int age;

Person(this.age);

//覆写 > 操作符
bool operator >(Person person) {
return this.age > person.age;
}

//覆写 [] 操作符
int operator [](String str) {
if ('age' == str) {
return age;
}

return 0;
}
}
CATALOG
  1. 1. 继承
  2. 2. 继承中的构造方法
    1. 2.1. 构造方法的执行顺序
  3. 3. 抽象类
  4. 4. 接口
  5. 5. Mixins
  6. 6. 操作符覆写