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
複製代碼
默認構造函數

若是未聲明構造函數,則會提供默認構造函數。 默認構造函數沒有參數,並在調用父類無參數構造函數。bash

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.
複製代碼
構造函數不能繼承

子類不能繼承其父類構造函數,一個沒有聲明構造函數的子類只有默認(無參數,無名稱)構造函數ide

命名構造函數

當咱們須要定義一個有特別含義的構造函數的時候,能夠經過構造函數.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");
  }
}
複製代碼
調用父類構造函數

默認狀況下,子類中的構造函數調用父類的未命名無參數構造函數。 父類的構造函數在子類構造函數體的開頭被調用。 若是還使用初始化了列表,則會在調用父類構造函數以前執行。 執行順序以下:ui

  • 初始化列表
  • 父類的無參數構造函數
  • 子類的無參數構造函數

若是父類沒有未命名的無參數構造函數,則必須手動調用父類中的一個構造函數。 在子類的構造函數體以後用冒號(:)指定父類構造函數this

例1:默認先調用父類的無參數構造函數spa

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:手動調用父類其餘構造函數code

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.
複製代碼

關於初始化列表: 調用父類構造函數以前,能夠在構造函數體執行以前初始化示例變量,用逗號分隔,該過程叫初始化列表。cdn

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');
複製代碼
相關文章
相關標籤/搜索