最多見的構造函數形式,即生成構造函數,建立一個類的新實例: 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');