美文网首页Flutter学习笔记
Dart值得注意的知识点(二)

Dart值得注意的知识点(二)

作者: WinJayQ | 来源:发表于2020-04-12 22:03 被阅读0次

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从入门到实战

相关文章

网友评论

    本文标题:Dart值得注意的知识点(二)

    本文链接:https://www.haomeiwen.com/subject/hzobmhtx.html