Dart中的类和单例模式

文章目录

  • Dart中的类和单例模式
    • 先了解Dart中的类:
      • 类的定义
      • 使用类的成员
      • 构造函数
      • 命名构造方法
      • 初始化列表
      • 重定向构造方法
      • 常量构造函数
      • 工厂构造方法
    • 类的继承
      • setter和getter
      • 类的继承
      • 抽象类
    • 多继承
      • 隐式接口
      • Mixin混入
    • 类的扩展extension
    • Flutter(able) 的单例模式
        • 方式一:普通单例
      • Dart 化单例
        • 方式二:利用getter操作符:
        • 方式三:利用工厂构造函数
        • 方式四:利用 Dart 空安全及箭头函数等特性 更加简洁
        • 方式五:利用操作符 `late ` 操作符(工厂构造函数+空安全+箭头函数)
      • Flutter 中的单例(Flutter化)
      • 小节:
      • 参考

Dart中的类和单例模式

先了解Dart中的类:

Dart也是一门面向对象的开发语言,面向对象中非常重要的概念就是类,通过类的初始化创建一个对象

Dart 是支持基于 mixin 继承机制的面向对象语言,所有对象都是一个类的实例,而除了 Null 以外的所有的类都继承自 Object 类。 基于 mixin 的继承 意味着尽管每个类(top class Object? 除外)都只有一个超类,一个类的代码可以在其它多个类继承中重复使用。 扩展方法 是一种在不更改类或创建子类的情况下向类添加功能的方式。

类的定义

  • Dart中,定义类用class关键字
  • 类通常有两部分组成:成员(member)和方法(method)。
  • 当未指明其父类的时候, 默认是继承自Object的, 定义类的伪代码如下:
class 类名 {
   
  类型 成员名;
  返回值类型 方法名(参数列表) {
   
    方法体
  }
}
  • Dart语言中, 在类中使用属性(成员/实例变量)时, 有必要时是通过this获取的
  • 但是下面在getsize方法中并没有加this
  • 这里需要注意的是: Dart的开发风格中,在方法中通常使用属性时,会省略this,但是有命名冲突时,this不能省略
// 创建类
class Point {
   
  // 定义变量
  int x;

  void getsize() {
   
    print('x = $x');
  }
}

// 类的初始化
main(List<String> args) {
   
    // 从Dart2开始,new关键字可以省略
    var point = new Point();
    point.x = 1;
    point.getsize();
}

使用类的成员

对象的 成员 由函数和数据(即 方法实例变量)组成。方法的 调用 要通过对象来完成,这种方式可以访问对象的函数和数据。

使用(.)来访问对象的实例变量或方法:

var p = Point(2, 2);

// Get the value of y.
assert(p.y == 2);

// Invoke distanceTo() on p.
double distance = p.distanceTo(Point(4, 4));

使用 ?. 代替 . 可以避免因为左边表达式为 null 而导致的问题:

// If p is non-null, set a variable equal to its y value.
var a = p?.y;

构造函数

  • 当通过类创建一个对象时,会调用这个类的构造方法
    • Dart语言中,如果类中没有明确指定构造方法时,将默认拥有一个无参的构造方法()
    • 上面得到的point对象调用的就是默认的无参构造方法
  • 也可以根据自己的需求自定义构造方法
    • 当我们创建了自己的构造方法时,默认的无参的构造方法将会失效,不能使用,否则会报错
    • 因为Dart本身不支持函数的重载, 所以如果我们明确的写一个默认的构造方法,就会和我们自定义的构造方法冲突
class Student {
   
  String name;
  int age;

  Student(String name, int age) {
   
    this.name = name;
    this.age = age;
  }
}
  • 在上面构造方法中主要实现的就是通过构造函数的参数给类的户型赋值
  • 为了简化这一过程, Dart提供了一种更加简洁的语法糖形式
class Student1 {
   
  String name;
  int age;

  // 这里和上面的Studeng的构造方法等价
  Student1(this.name, this.age);
}

命名构造方法

  • 在实际开发中, 很明显一个构造方法的确是不够我们使用的
  • 而且Dart又不支持函数的重载, 不能创建爱你相同名称不同参数的构造方法
  • 这就衍生出了另外一中构造方法:命名构造方法
class Model {
   
  String name;
  int age;

  Model(this.name, this.age);

  // 命名构造方法
  Model.withNameAndAge(String name, int age) {
   
    this.name = name;
    this.age = age;
  }
  // 命名构造方法
  Model.initJson(Map<String, Object> map) {
   
    this.name = map['name'];
    this.age = map['age'];
  }
}


// 初始化对象
main() {
   
  // 普通构造方法
  var model0 = Model('name', 12);
  // 命名构造方法
  var model1 = Model.withNameAndAge('titan', 12);
  var model2 = Model.initJson({
   'name': 'jun', 'age': 18});
}

初始化列表

几种方式定义的属性都是可变的, 如果定义的属性是final不可重新赋值的又该如何实现

class Teacher {
   
  final String name;
  final int age;

  // 1. 这里会有一个错误提示: All final variables must be initialized, but 'age' and 'name' are not
  Teacher(String name, int age) {
   
    //2. 这里也会有一个错误提示: 'name' can't be used as a setter because it's final
    this.name = name;
    this.age = age;
  }
}
  • 上面第一处错误主要是因为: 在Dart中在执行下面{ }中的代码的时候, 表示Teacher对象已经初始化完毕了

你可能感兴趣的:(Flutter,flutter,android,android,studio,ios)