Flutter学习之Dart语言基础(构造函数)

最多见的构造函数形式,即生成构造函数,建立一个类的新实例:

class Point {
  num x, y; //Dart中int和double是num的子类

  //this引用当前类对象
  Point(num x, num y) {
    this.x = x;
    this.y = y;
  }
}



使用语法糖的时候能够这样定义:

class Point {
  num x, y;

  //用于设置x和y的语法糖
  //在构造函数体运行以前
  Point(this.x, this.y);

  @override
  String toString() {
    return ("x: $x, y: $y");
  }
}

//print(new Point(100, 200)); -> 打印 x: 100, y: 200


默认构造函数

若是未声明构造函数,则会提供默认构造函数。 默认构造函数没有参数,并在调用父类无参数构造函数。

class Parent{
  Parent(){
    print('In Parent\'s constructor.');
  }
}

class Child extends Parent{
  Child(){
    print('In Child\'s constructor.');
  }
}

//new Child(); -> 打印 In Parent's constructor.  In Child's constructor.



构造函数不能继承

子类不能继承其父类构造函数,一个没有声明构造函数的子类只有默认(无参数,无名称)构造函数
命名构造函数

当咱们须要定义一个有特别含义的构造函数的时候,能够经过构造函数.XXX来命名构造函数

class Point{
  num x;
  num y;

  Point(this.x, this.y);
  
  //建立一个坐标原点类
  Point.origin(){
    this.x = 0;
    this.y = 0;
  }

 //建立一个坐标为(100, 100)的类
 Point.coordinate100(){
    this.x = 100;
    this.y = 100;
  }
  @override
  String toString() {
    return ("x: $x, y: $y");
  }
}



调用父类构造函数

默认状况下,子类中的构造函数调用父类的未命名无参数构造函数。 父类的构造函数在子类构造函数体的开头被调用。 若是还使用初始化了列表,则会在调用父类构造函数以前执行。 执行顺序以下:

    初始化列表
    父类的无参数构造函数
    子类的无参数构造函数

若是父类没有未命名的无参数构造函数,则必须手动调用父类中的一个构造函数。 在子类的构造函数体以后用冒号(:)指定父类构造函数

例1:默认先调用父类的无参数构造函数

class Parent{
  Parent(){
    print('In Parent\'s constructor.');
  }
}


class Child extends Parent{
  Child(num x, num y) {
    print('In Child\'s constructor.');
  }
}

//new Child(100, 100); -> 打印
//In Parent's constructor.
//In Child's constructor.


例2:手动调用父类其余构造函数

class Parent{
  num x;
  num y;
  Parent(this.x, this.y){
    print('In Parent\'s constructor.');
  }
}

class Child extends Parent{
  Child(num x, num y) : super(x, y){
    print('In Child\'s constructor.');
  }
}

//new Child(100, 100); -> 打印
//In Parent's constructor.
//In Child's constructor.


关于初始化列表:
调用父类构造函数以前,能够在构造函数体执行以前初始化示例变量,用逗号分隔,该过程叫初始化列表。

class Parent{
  num x;
  num y;
  num sum;

  Parent(num px, num py) : x = px, y = py, sum = px + py{
    print("x: $x, y: $y, sum: $sum");
    print('In Parent\'s constructor.');
  }
}

class Child extends Parent{
  Child(num x, num y) : super(x, y){
    print('In Child\'s constructor.');
  }
}

// new Child(100, 100); -> 打印
//x: 100, y: 100, sum: 200
//In Parent's constructor.
//In Child's constructor.


重定向构造函数

有时构造函数须要重定向到同一个类中的另外一个构造函数,在冒号后面用this:

class Point {
  num x, y;

  //类的主构造函数
  Point(this.x, this.y);

  //重定向到主构造函数
  Point.alongXAxis(num x) : this(x, 0);
}



常量构造函数

若是你的类须要成为永远不会更改的对象,则可使这些对象成为编译时常量。 定义const构造函数要确保全部实例变量都是final。

class Point {
  final num x;
  final num y;
  static final Point2 origin = const Point2(0, 0);

  //const关键字放在构造函数名称以前,且不能有函数体
  const Point2(this.x, this.y);
}


没有定义final时提示:
const-construcot.png

使用函数体时提示:
const-construcot.png
工厂构造函数

在实现不用老是建立新的类对象的时候,可使用factory关键字。 例如,工厂构造函数可能从缓存中返回实例,或者它可能返回子类型的实例:

class Logger {
  final String name;
  bool mute = false;

  //工厂构造函数没法访问this,因此这里要用static
  //维护一个缓存的Map对象,
  static final Map<String, Logger> _cache =
      <String, Logger>{};
  
 //调用该构造函数的时候,会从Map中取出对象
  factory Logger(String name) {
    if (_cache.containsKey(name)) {
      return _cache[name];
    } else {
      final logger = Logger._internal(name);
      _cache[name] = logger;
      return logger;
    }
  }

  Logger._internal(this.name);

  void log(String msg) {
    if (!mute) print(msg);
  }
}

//调用
var logger = Logger('UI');
logger.log('Button clicked');
相关文章
相关标签/搜索