【笔记】Dart的面向对象

前言

Dart的面向对象学习笔记

定义类

  • 类名首字母大写
1
2
3
class 类名 {
...
}

类中定义属性

1
2
3
class 类名 {
数据类型 属性名 = 属性值;
}

类中定义方法

1
2
3
4
5
class 类名 {
返回值类型 方法名(参数列表) {
...
}
}

类中定义构造方法

  • 构造方法在对象被创建时立即执行,用于初始化对象
  • 构造方法名与类同名
  • 构造方法没有返回值,且无需void关键字
默认构造方法
  • 通过类创建对象时,通常使用默认构造方法创建对象
  • 每个类只能包含一个默认构造方法
无参构造
1
2
3
4
5
class 类名 {
类名() {
...
}
}
  • 初始化属性
1
2
3
4
5
6
7
8
class 类名 {

数据类型 属性名;

类名():属性名=属性值 {
...
}
}
有参构造
  • 初始化属性
1
2
3
4
5
6
7
8
class 类名 {

数据类型 属性名;

类名(属性名) {
属性名 = this.属性名;
}
}
  • 简写
1
2
3
4
5
6
class 类名 {

数据类型 属性名;

类名(this.属性名);
}
命名构造方法
  • 通过类创建对象时,也可以使用命名构造方法创建对象
  • 每个类可以包含多个命名构造方法
1
2
3
4
5
6
7
8
class 类名 {

数据类型 属性名;

类名.构造方法名(属性名) {
属性名 = this.属性名;
}
}

实例化类为对象

通过默认构造方法

1
类名 对象名 = new 类名();

通过命名构造方法

1
类名 对象名 = new 类名.构造方法名();

省略new关键字

1
数据类型 对象名 = 数据类型();

通过常量构造方法创建对象

  • 创建对象时添加const关键字,可以使对象指向相同的内存空间
1
数据类型 对象名 = const new 数据类型();

获取对象中的属性

1
对象名.属性名;

调用对象的方法

1
对象名.方法名(参数列表);

模块化

分离类为独立dart文件

User.dart

1
2
3
class User {
...
}

其他dart文件引入类

1
2
3
import "User.dart";

User user = new User;

私有权限

  • 可以通过在类内部的属性名和方法名添加_作为前缀,那么这个属性名和方法名就成为了私有属性和私有方法
  • 必须把类分离为独立dart文件,才能实现私有权限
1
2
3
4
5
6
7
8
class 类名 {

数据类型 _私有属性名;

返回值类型 _私有方法名(参数列表) {
...
}
}

Getter方法

定义Getter方法

  • Getter方法的返回值类型用get修饰
  • Getter方法没有参数列表,也不需要使用()定义无参
1
2
3
4
5
class 类名 {
get Getter方法名 {
return 值;
}
}

使用Getter方法

  • 如果一个类中已经定义了Getter方法,那么可以直接通过调用Getter方法名的方式获取Getter的返回值
1
2
类名 变量名 = new 类名();
变量名.Getter方法名;

Setter方法

定义Setter方法

  • Setter方法的返回值类型用set修饰
  • Setter方法的参数列表用于传递需要修改的变量的新值
1
2
3
4
5
6
7
8
class 类名 {

数据类型 属性名;

set Setter方法名(新值) {
属性名 = 新值;
}
}

使用Setter方法

1
2
类名 变量名 = new 类名();
变量名.Setter方法名(新值);

静态属性和静态方法

  • 通过static关键字修饰的属性是静态属性;通过static关键字修饰的方法是静态静态
  • 静态属性和方法可以通过类名直接访问,也可以通过对象访问
  • 静态属性和方法的数据存放在堆中,所有对象共享
  • 静态方法不能访问非静态方法,非静态方法可以访问静态方法
  • 在非静态方法中调用当前类中的属性,推荐直接使用属性名的方式调用静态属性;在非静态方法中调用当前类中的属性,推荐使用this.属性名的方式调用非静态属性
1
2
3
4
5
6
7
8
class{

static 数据类型 属性名;

static void 方法名() {
...
}
}

对象操作符

条件运算符

  • 通过?关键字修饰对象,可以对对象进行非空判断
    • 如果对象为空,则不执行调用的方法
    • 如果对象不为空,则执行调用的方法
1
2
类名 对象名;
对象名?.方法名();

类型判断

  • 通过is关键字,来判断对象是否属于类型,返回布尔值
1
对象名 is 类名;

类型转换

  • 通过as关键字,将对象强制类型转换为指定类
1
对象名 as 类名;

连缀操作

  • 通过..关键字,连续调用同一对象的属性或方法
1
2
对象名..属性名 = 属性值
..方法名()

继承

  • 子类只能继承一个父类
1
2
3
4
5
6
7
class Father {
...
}

class Son extends Father {
...
}

构造方法

  • 子类不能继承父类的构造方法,需要重新定义构造方法
  • 通常将子类构造方法得到的参数传递给父类进行赋值
1
2
3
4
5
6
7
8
class Father {
String name;
Father(this.name);
}

class Son extends Father {
Son(String name) : super(name);
}

方法的重写

  • 子类重写父类方法时,在方法的上一行使用@override注解标注
1
2
3
4
5
6
7
8
9
10
11
12
class Father {
void method() {
...
}
}

class Son extends Father {
@override
void method() {
...
}
}

子类调用父类的属性和方法

  • 子类通过supper关键字调用父类的属性和方法
1
2
3
4
5
6
7
8
9
10
11
12
13
class Father {
String name;
void method() {
...
}
}

class Son extends Father {
void method() {
super.name;
super.method();
}
}

定义抽象类

  • 通过abstract关键字修饰的类就是抽象类
  • 在抽象类中定义没有方法体的方法就是抽象方法
  • 子类继承抽象类必须重写父类中的抽象方法
  • 抽象类中也可以定义普通方法
1
2
3
4
5
6
7
8
9
10
abstract class Father {
void method();
}

class Son extends Father {
@override
void method() {
...
}
}

多态

  • 允许将子类类型的指针赋值给父类类型的指针,同一方法调用会有不同的效果
1
2
3
4
5
6
7
8
9
10
11
abstract class Father {
...
}

class Son extends Father {
...
}

main() {
Father s = new Son();
}

定义接口

  • Dart中没有实际意义上的接口,而是通过一个抽象类定义一个接口
    • 通常使用抽象类定义接口,在作为接口的抽象类中,只定义抽象方法不定义普通方法
  • 子类通过implements实现接口,实现接口的子类需要重写父类的全部属性和全部方法
  • 子类可以实现多个接口

实现一个接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
abstract class Father {
String name;
void method();
}

class Son implements Father {
@override
String name;

@override
void method() {
...
}
}

实现多个接口

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
abstract class Father {
String fatherName;
void fatherMethod();
}

abstract class Mother {
String motherName;
void motherMethod();
}

class Son implements Father,Mother {
@override
String fatherName;
@override
String motherName;

@override
void fatherMethod() {
...
}
@override
void motherMethod() {
...
}
}

mixins

  • mixins不是继承也不是接口,而是一种全新的特性,但是通过mixins关键字实现类似多继承
  • 作为mixins的类只能继承自Object,不能继承其他类
  • 作为mixins的类不能有构造函数
  • 一个类可以mixins多个mixins类
  • 如果多个mixins类出现了相同方法,后mixins的类中的方法会覆盖先mixins的类中的方法
  • mixins后的类型为所有mixins类的超类
1
2
3
4
5
6
7
8
9
10
11
class Father {
...
}

class Mother {
...
}

class Son with Father,Mother {
...
}

泛型

  • 解决类、接口、方法的复用性,以及对不特定数据类型的支持
  • 在方法名后通过<T>定义泛型,尖括号内可以用任意字母表示泛型,通常使用T

泛型方法

1
2
3
4
5
T method<T>(T t) {
return t;
}

method<实际类型>(实际类型的参数);

泛型类

1
2
3
4
5
class 类名<T> {
...
}

new 类名<实际类型>();

泛型接口

  • 实现泛型接口的类必须也是泛型类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
abstract class Father<T> {
String name;

void method();
}

class Son<T> implements Father<T> {
@override
String name;

@override
void method() {
...
}
}

完成

参考文献

哔哩哔哩——筱筱知晓