Flutter開發Dart極速入門 (類和對象)

一般構造函數

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()}');
  }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章