1. 程式人生 > 實用技巧 >【dart 學習】 建構函式

【dart 學習】 建構函式

dart 建構函式

ClassName(...) //普通建構函式

普通建構函式
這就是我們普通的建構函式,其樣子和其它語言幾乎一樣

class Point {
  num x, y;

  Point(num x, num y) {
    // There's a better way to do this, stay tuned.
    this.x = x;
    this.y = y;
  }
}
上例中只有兩個成員變數,如果有10個,豈不是麻煩死?所以Dart有語法糖給你哦:

class Point {
  num x, y;

  // Syntactic sugar for setting x and y
  
// before the constructor body runs. Point(this.x, this.y); } 它可以將x,y的賦值變得簡單一些,就不用寫建構函式的方法體了,記得括號後用分號哦。 Classname.identifier(...) //命名建構函式 命名建構函式 class Point { num x, y; Point(this.x, this.y); // 命名建構函式,新增程式碼 Point.origin() { x = 0; y = 0; } } 請記住,命名建構函式不可繼承,如果子類想要有 和父類一樣的命名建構函式,那就寫個同名的(通常也會在子類的命名建構函式裡,呼叫父類的同名命名建構函式)
const ClassName(...) //常量建構函式 常量建構函式總結如下幾點: 常量建構函式需以const關鍵字修飾 const建構函式必須用於成員變數都是final的類 構建常量例項必須使用定義的常量建構函式 如果例項化時不加const修飾符,即使呼叫的是常量建構函式,例項化的物件也不是常量例項 下面結合例項,對以上幾點加以說明 正確的常量建構函式定義 根據以上的總結,定義一個Point類,包含一個常量建構函式,注意其成員變數都是final型別,且建構函式用const修飾 class Point { final int x; final int y; const
Point(this.x, this.y); } 常量建構函式需以const關鍵字修飾 如下程式碼定義一個const物件,但是呼叫的構造方法不是const修飾的,則會報The constructor being called isn't a const constructor.錯誤 void main() { const point = Point(1, 2); // 報錯 } class Point { final int x; final int y; Point(this.x, this.y); } const建構函式必須用於成員變數都是final的類 如下程式碼中成員變數x為非final,會報Can't define a const constructor for a class with non-final fields.錯誤 class Point { int x; final int y; const Point(this.x, this.y); } 構建常量例項必須使用定義的常量建構函式 如下程式碼,定義一個const物件,但是呼叫的卻是非常量建構函式,會報The constructor being called isn't a const constructor.錯誤 void main() { var point = const Point(1, 2); // 報錯 print(point.toString()); } class Point { int x; int y; Point(this.x, this.y); // 非const建構函式 String toString() { return 'Point(${x}, ${y})'; } } 如果例項化時不加const修飾符,即使呼叫的是常量建構函式,例項化的物件也不是常量例項 如下程式碼,用常量建構函式構造一個物件,但是未用const修飾,那麼該物件就不是const常量,其值可以再改變 void main() { var point = Point(1, 2); // 呼叫常量建構函式,但是未定義成常量 print(point.toString()); point = Point(10, 20); // 可以重新賦值,說明定義的變數為非常量 print(point.toString()); } class Point { final int x; final int y; const Point(this.x, this.y); String toString() { return 'Point(${x}, ${y})'; } } factroy ClassName(...) //工廠建構函式 工廠建構函式的定義 工廠建構函式是一種建構函式,與普通建構函式不同,工廠函式不會自動生成例項,而是通過程式碼來決定返回的例項物件. 工廠建構函式的關鍵字為factory,下面我們用工廠建構函式寫一個只能創造一個例項的類. class A{ String name; static A cache; factory A([String name='A']){ if(A.cache===null){ A.cache=new A.newObject(name); } return A.cache; } A.newObject(this.name); } void main(){ A a=new A('HelloWorld'); print(a.name); A b=new A('HelloDart'); print(b.name); print(a===b); } A類具有一個名為cache的靜態成員,它將快取A類的第一個例項. 在工廠建構函式A中,首先判斷A.cache是否已經存在例項(即判斷是否是第一次例項化),如果存在則返回快取的例項,不存在則新建一個例項並快取. A.newObject是一個命名建構函式,用於建立例項. 執行這段程式碼,會輸出 HelloWorld HelloWorld true 其中字串”HelloWorld”是第一個例項的name成員,在宣告變數b時改用了”HelloDart”,但返回的例項的name成員仍然是”HelloWorld”. 再用===運算子判斷一下它們是否屬於同一個物件,結果為true,變數a和b指向的是同一個物件. 3.8.2 工廠建構函式的特性 工廠建構函式類似於static靜態成員,無法訪問this指標,所以在工廠建構函式中能處理的任務較為有限. 使用工廠建構函式時往往需要定義一個命名建構函式用來生產例項. 注意點 初始化列表 初始化列表的執行順序,在整個建構函式的最前面,它除了可以呼叫父類的建構函式,還可以在建構函式方法體之前,初始化一些成員變數。 // Initializer list sets instance variables before // the constructor body runs. Point.fromJson(Map<String, num> json) : x = json['x'], y = json['y'] { print('In Point.fromJson(): ($x, $y)'); } 尤其是初始化那些final修飾的成員變數時,初始化列表很有用,因為在方法體中,不能給final修飾的成員變數賦值,因為在執行方法體的時候,final修飾的成員變數已經不能變了。這個地方很多人犯錯。 import 'dart:math'; class Point { final num x; final num y; final num distanceFromOrigin; Point(x, y) : x = x, y = y, distanceFromOrigin = sqrt(x * x + y * y); } main() { var p = new Point(2, 3); print(p.distanceFromOrigin); } 參考: 連結:https://www.jianshu.com/p/a0ba5f2ac5ce