1. ??=赋值操作
dart有一个很多语言都不具备的赋值运算符:
- 当变量为null时,使用后面的内容进行赋值。
- 当变量有值时,使用自己原来的值。
main(List<String> args) {
var name = 'aaa';
// var name = null;
name ??= 'bbb';
print(name); // 当name初始化为aaa时,结果为aaa,当初始化为null时,赋值了bbb
}
2.条件运算符
Dart中包含一直比较特殊的条件运算符:expr1 ?? expr2
- 如果expr1是null,则返回expr2的结果;
- 如果expr1不是null,直接使用expr1的结果。
var temp = 'aaa';
// var temp = null;
var name = temp ?? 'bbb';
print(name);
3.级联语法:..
- 某些时候,我们希望对一个对象进行连续的操作,这个时候可以使用级联语法
class Person {
String name;
void run() {
print("${name} is running");
}
void eat() {
print("${name} is eating");
}
void swim() {
print("${name} is swimming");
}
}
main(List<String> args) {
final p1 = Person();
p1.name = 'xiaoming';
p1.run();
p1.eat();
p1.swim();
final p2 = Person()
..name = "zhangsan"
..run()
..eat()
..swim();
}
4.类的定义
在Dart中,定义类用class关键字。
类通常有两部分组成:成员(member)和方法(method)。
定义类的伪代码如下:
class 类名 {
类型 成员名;
返回值类型 方法名(参数列表) {
方法体
}
}
- 这里有一个注意点: Dart的开发风格中,在方法中通常使用属性时,会省略this,但是有命名冲突时,this不能省略;
4.1 构造方法
4.1.1普通构造方法
- 当类中没有明确指定构造方法时,将默认拥有一个无参的构造方法。
我们也可以根据自己的需求,定义自己的构造方法:
注意一:当有了自己的构造方法时,默认的构造方法将会失效,不能使用
当然,你可能希望明确的写一个默认的构造方法,但是会和我们自定义的构造方法冲突;这是因为Dart本身不支持函数的重载(名称相同, 参数不同的方式)。
Dart提供了一种简洁的语法糖形式.
Person(String name, int age) {
this.name = name;
this.age = age;
}
// 等同于
Person(this.name, this.age);
4.1.2. 命名构造方法
但是在开发中, 我们确实希望实现更多的构造方法,怎么办呢?
因为不支持方法(函数)的重载,所以我们没办法创建相同名称的构造方法。
我们需要使用命名构造方法:
class Person {
String name;
int age;
Person() {
name = '';
age = 0;
}
// 命名构造方法
Person.withArgments(String name, int age) {
this.name = name;
this.age = age;
}
@override
String toString() {
return 'name=$name age=$age';
}
}
// 创建对象
var p1 = new Person();
print(p1);
var p2 = new Person.withArgments('why', 18);
print(p2);
在之后的开发中, 我们也可以利用命名构造方法,提供更加便捷的创建对象方式:
比如开发中,我们需要经常将一个Map转成对象,可以提供如下的构造方法
// 新的构造方法
Person.fromMap(Map<String, Object> map) {
this.name = map['name'];
this.age = map['age'];
}
// 通过上面的构造方法创建对象
var p3 = new Person.fromMap({'name': 'kobe', 'age': 30});
print(p3);
4.1.3 常量构造方法
默认情况下,创建对象时,即使传入相同的参数,创建出来的也不是同一个对象
在某些情况下,传入相同值时,我们希望返回同一个对象,这个时候,可以使用常量构造方法.
- 将构造方法前加const进行修饰,那么可以保证同一个参数,创建出来的对象是相同的,这样的构造方法就称之为常量构造方法。
main(List<String> args) {
var p1 = const Person('aaa');
var p2 = const Person('aaa');
print(identical(p1, p2)); // true
}
class Person {
final String name;
const Person(this.name);
}
常量构造方法有一些注意点:
注意一:拥有常量构造方法的类中,所有的成员变量必须是final修饰的.
注意二: 为了可以通过常量构造方法,创建出相同的对象,不再使用 new关键字,而是使用const关键字
如果是将结果赋值给const修饰的标识符时,const可以省略.
4.2 抽象类
我们知道,继承是多态使用的前提。
所以在定义很多通用的调用接口时, 我们通常会让调用者传入父类,通过多态来实现更加灵活的调用方式。
但是,父类本身可能并不需要对某些方法进行具体的实现,所以父类中定义的方法,,我们可以定义为抽象方法。
什么是 抽象方法? 在Dart中没有具体实现的方法(没有方法体),就是抽象方法。
- 抽象方法,必须存在于抽象类中。
- 抽象类是使用abstract声明的类。
下面的代码中, Shape类就是一个抽象类, 其中包含一个抽象方法.
abstract class Shape {
getArea();
}
class Circle extends Shape {
double r;
Circle(this.r);
@override
getArea() {
return r * r * 3.14;
}
}
class Reactangle extends Shape {
double w;
double h;
Reactangle(this.w, this.h);
@override
getArea() {
return w * h;
}
}
注意事项:
- 注意一:抽象类不能实例化.
- 注意二:抽象类中的抽象方法必须被子类实现, 抽象类中的已经被实现方法, 可以不被子类重写.
4.3 Mixin混入
在通过implements实现某个类时,类中所有的方法都必须被重新实现(无论这个类原来是否已经实现过该方法)。
但是某些情况下,一个类可能希望直接复用之前类的原有实现方案,怎么做呢?
- 使用继承吗?但是Dart只支持单继承,那么意味着你只能复用一个类的实现。
Dart提供了另外一种方案: Mixin混入的方式
- 除了可以通过class定义类之外,也可以通过mixin关键字来定义一个类。
- 只是通过mixin定义的类用于被其他类混入使用,通过with关键字来进行混入。
学习内容来自Flutter从入门到实战