類
一般構造函數
main() {
Point point;
point = Point(1, 2);
print('${point.x} ${point.y}'); // print: 1 2
}
class Point {
int x;
int y;
// 基本寫法
Point(this.x, this.y);
}
命名構造函數
main() {
Point point;
point = Point.myPoint(1, 10);
print('${point.x} ${point.y}'); // print: 1 10
}
class Point {
int x;
int y;
// 命名構造函數
Point.myPoint(this.x, this.y);
}
重定向構造函數
main() {
Point point;
point = Point.rePoint(2);
print('${point.x} ${point.y}'); // print: 0 3
}
class Point {
int x;
int y;
// 重定向構造函數, 使用 ":" 調用其他函數
Point.rePoint(n) : this(0, n);
}
初始化列表
main() {
Point point;
point = Point(1, 2);
print('${point.x} ${point.y}'); // print: 1 3
}
class Point {
int x;
int y;
// 類初始化列表
Point(x, y)
: x = x,
y = y + 1;
}
調用超類的構造函數
main() {
Child(2, 4);
Child.cons(2, 4);
}
class Parent {
int x;
int y;
Parent.cons(this.x, this.y) {
print('Parent 構造函數');
}
}
class Child extends Parent {
int x;
int y;
// 如果超類沒有默認構造函數, 則你需要手動的調用超類的其他構造函數
Child(x, y): x = x, y = y, super.cons(x, y){
print('子類構造函數 x:${this.x}, y:${this.y}');
}
// 超類命名構造函數不會傳遞,如果希望使用超類中定義的命名構造函數創建子類,則必須在子類中實現該構造函數
Child.cons(x, y)
: x = x,
y = x * y,
super.cons(x, y) {
print('子類構造函數 x:${this.x}, y:${this.y}');
}
}
常量構造函數
main() {
var p2 = Point2(0,0); // 創建的是非常量構造函數
var p21 = const Point2(0,0); // 常量構造函數
var p22 = Point2.point2; // 常量構造函數
print(identical(p21, p2)); // print: false
print(identical(p21, p22)); //print: true
}
// 常量構造函數
class Point2 {
// 定義const構造函數要確保所有變量都是final
final num x;
final y;
static final Point2 point2 = const Point2(0, 0);
// const關鍵字放在構造函數名之前, 不能有函數體
const Point2(this.x, this.y);
@override
String toString() {
return 'Point2(x = $x, y = $y)';
}
}
工廠構造函數
-
工廠構造函數實現單例
main() { var single1 = SingleInstance('Android'); var single2 = SingleInstance('dart'); print(identical(single1, single2)); // print: true } // 工廠構造函數實現單例 class SingleInstance { String name; static SingleInstance _instance; SingleInstance._newInstance(this.name); factory SingleInstance([name = "factory: single instance"]) => SingleInstance._instance ??= SingleInstance._newInstance(name); }
-
工廠模式
main() { Message("Android").doMessage(); // print: FlutterMessage. Message("Dart").doMessage(); // print: DartMessage. Message("Flutter").doMessage(); // print: FlutterMessage. } abstract class Message { factory Message(type) { switch (type) { case 'Dart': return DartMessage(); case 'Flutter': default: return FlutterMessage(); } } void doMessage(); } class DartMessage implements Message { @override void doMessage() { print('DartMessage.'); } } class FlutterMessage implements Message { @override void doMessage() { print('FlutterMessage.'); } }
Setter和Getter
//每個實例變量都隱含的具有一個 getter, 如果變量不是 final 的則還有一個 setter
//可以通過實行 getter 和 setter 來創建新的屬性, 使用 get 和 set 關鍵字定義 getter 和 setter
class Rectangle {
num left;
num top;
num width;
num height;
Rectangle(this.left, this.top, this.width, this.height);
// getter 和 setter 的好處是,可以開始使用實例變量,後面可以把實例變量用函數包裹起來,而調用你代碼的地方不需要修改。
//獲取right值
num get right => left + width;
//設置right值,同時left也發生變化
set right(num value) => left = value - width;
//獲取bottom值
num get bottom => top + height;
//設置bottom值,同時top也發生變化
set bottom(num value) => top = value - height;
}
擴展類
-
使用 extends 創建一個子類,同時 supper 將指向父類
class Television { void turnOn() { _illuminateDisplay(); _activateIrSensor(); } } class SmartTelevision extends Television { void turnOn() { super.turnOn(); _bootNetworkInterface(); _initializeMemory(); _upgradeApps(); } }
-
多繼承
class AB extends P with A, B {}
如果2個或多個超類擁有相同簽名的A方法, 那麼子類會以繼承的最後一個超類中的A方法爲準
如果子類自己重寫了A方法則以本身的A方法爲準
可調用類
可調用類, 允許像函數一樣調用Dart類
main() {
var iClazz = new InvokeClass();
var out = iClazz('Android', 'Dart', 'Flutter');
print('$out'); // print: Android, Dart, Flutter
print(iClazz.runtimeType); // print: InvokeClass
print(out.runtimeType); // print: String
print(out is Function); // print: false
}
class InvokeClass {
call(String a, String b, String c) => '$a, $b, $c';
}
Mixin
Mixins 是在多個類層次結構中重用類代碼的一種方式
如下示例, Student 和 Painter分別可以’寫作業’和’畫畫’, 同時也都可以’跑步’
main() {
Student('Tom').say();
Painter('Jack').say();
}
abstract class Person {
var name;
Person(this.name);
say();
}
mixin Run {
run() => '跑步';
}
mixin HomeWork {
work() => '寫作業';
}
mixin Painting {
work() => '畫畫';
}
class Student extends Person with Run, HomeWork {
Student(name) : super(name);
@override
say() {
print('Student name is $name, 他可以${work()}');
print('Student ${run()}');
}
}
class Painter extends Person with Run, Painting {
Painter(name) : super(name);
@override
say() {
print('Painter name is $name, 他可以${work()}');
print('Painter ${run()}');
}
}
Mixin on
超類約束
如下, HomeWork 聲明瞭 Eat 上的超類約束, 表示如果要使用 HomeWork, 這個類就必須繼承或實現 Eat. (要讓Student寫作業, 就必須要讓Student吃飯)
main() {
Student('Tom').say();
Painter('Jack').say();
}
abstract class Person {
var name;
Person(this.name);
say();
}
mixin Eat {
String doEat();
}
mixin HomeWork on Eat{ // 聲明超類約束
work() => '寫作業';
}
mixin Painting {
work() => '畫畫';
}
// 要使用HomeWork必須實現Eat
class Student extends Person with Eat, HomeWork{
Student(name) : super(name);
@override
say() {
print('Student name is $name, 他可以${work()}, 但是要先${doEat()}');
}
@override
doEat() => '吃飯';
}
class Painter extends Person with Painting{
Painter(name) : super(name);
@override
say() {
print('Painter name is $name, 他可以${work()}');
}
}