Flutter5 類、範型和流程控制

RainDou發表於2019-09-12

本文對應github地址Flutter5,如果由於github調整導致資源找不到,請訪問github

類和抽象類

  • 抽象類(abstract class)不能例項化
  • 可以當做抽象類來 extends
  • 抽象類也可以當做介面來 implements
  • dart中沒有interface關鍵字,介面是用抽象類實現的
  • 如果一個類同時有繼承、混入、介面實現,那麼extens在前,with在中間,implements最後

繼承(Inheritance) extends

  • Dart的繼承是單繼承

  • 建構函式不能繼承

  • 子類重寫超類的方法,要用@override

  • 子類呼叫超類的方法,要用super

  • Dart中的子類可以訪問父類中的所有變數和方法(只有下劃線開頭私有)

  • 抽象類可以被繼承,然後實現其抽象方法

    abstract class Animal {
      eat(); // 未實現,抽象方法,子類必須實現
      printInfo() { // 已經實現,子類不必須實現
        print("Animal printInfo");
      }
    }
    
    class Cat extends Animal {
      @override
      eat() {
        print("Cat eat fish");
      }
    }
    
    class Dog extends Animal {
    
      @override
      eat() {
        print('Dog eat bone');
      }
    }
    
    // 抽象類測試
    testAbstractClass() {
      Dog dog = new Dog();
      Cat cat = new Cat();
    
      dog.eat(); // Dog eat bone
      cat.eat(); // Cat eat fish
    
      dog.printInfo(); // Animal printInfo
      cat.printInfo(); // Animal printInfo
    }
    複製程式碼

介面實現 implements

  • 介面也是 abstract 關鍵字宣告的,並且需要使用 implements 關鍵字來實現

    // 抽象類介面
    abstract class PersonDataBase {
      String userName;
      String passWord;
    
      getUserNameWithPassWord(String passWord);
      resetPassWordOfUserName(String userName);
    }
    
    // implements 實現抽象類介面
    class StudentDataBase implements PersonDataBase {
      @override
      String passWord;
    
      @override
      String userName;
    
      @override
      getUserNameWithPassWord(String newPassWord) {
        if (newPassWord == passWord) {
          print("${userName}");
        } else {
          print("PassWord Error");
        }
      }
    
      @override
      resetPassWordOfUserName(String userName) {
        if (userName == this.userName) {
          this.passWord = "admin";
          print("reset success");
        } else {
          print("userName error");
        }
      }
    
      StudentDataBase(this.userName, [this.passWord = "admin"]) {
        print("userName: ${this.userName} passWord: ${this.passWord}");
      }
    }
    
    // 介面實現測試
    testImplements() {
      StudentDataBase studentDB = new StudentDataBase("LiBai", "10086"); // userName: LiBai passWord: 10086
      studentDB.getUserNameWithPassWord("admin"); // PassWord Error
      studentDB.getUserNameWithPassWord("10086"); // LiBai
      studentDB.resetPassWordOfUserName("LiLei"); // userName error
      studentDB.resetPassWordOfUserName("LiBai"); // reset success
      studentDB.getUserNameWithPassWord("10086"); // PassWord Error
      studentDB.getUserNameWithPassWord("admin"); // LiBai
    }
    複製程式碼

多介面

  • 多個介面用逗號,分隔

    abstract class Person {
      sleep();
    }
    
    abstract class Student {
      study();
    }
    
    class Pupil implements Person, Student {
      @override
      sleep() {
        print("Pupil also need sleep");
      }
    
      @override
      study() {
        print("Pupil also need study");
      }
    }
    
    // 多介面測試
    testSomeImplements() {
      Pupil pupils = Pupil();
      pupils.sleep(); // Pupil also need sleep
      pupils.study(); // Pupil also need study
    }
    複製程式碼

混入 mixin

  • mixins類只能繼承自object

  • mixins類不能有建構函式

  • 一個類可以mixins多個mixins類

  • 可以mixins多個類,不破壞Flutter的單繼承

    // 混入 mixin
    class Plant {
      info() {
        print("Plant don't move");
      }
    }
    
    abstract class Tree {
      leaf();
      root() {
        print("Tree has the root");
      }
    }
    
    class AppleTree extends Object with Plant, Tree {
      @override
      leaf() {
        print("AppleTree has leaves");
      }
    }
    
    // 混入(mixin)測試
    testMixinWith() {
      AppleTree appleTree = new AppleTree();
      appleTree.info(); // Plant don't move
      appleTree.root(); // Tree has the root
      appleTree.leaf(); // AppleTree has leaves
    }
    複製程式碼

列舉

  • 列舉是一種特殊的類,通常用來表示相同型別的一組常量
  • 列舉的每一個值都有一個index屬性,index從0開始計數。
  • 列舉不能被繼承,不能建立例項
enum Animal {
  cat,
  dog,
  bird
}
複製程式碼

範型

  • 範型方法

    T getData<T> (T val) {
      return val;
    }
    
    getData<String>('123');
    getData<int>(123);
    // getData<int>(123.4); // 報錯,型別不匹配
    複製程式碼
  • 泛型類

  1. 宣告泛型類,如Array類,實際是List的別名,而List本身也支援泛型的實現

    class Array<T> {
      List _list = new List<T>();
      Array();
      void add<T>(T value) {
        this._list.add(value);
      }
      get value {
        return this._list;
      }
    }
    複製程式碼
  2. 使用泛型類

    List l1 = new List<String>();
    // l1.add(12); // 型別不匹配
    l1.add('asd');
    複製程式碼
  • 泛型介面

    // 範型介面
    abstract class Storage<T> {
      Map mapIn = new Map();
      void set(String key, T value);
      T get(String key);
    }
    
    class Cache<T> implements Storage<T> {
      @override
      Map mapIn = new Map();
    
      @override
      T get(String key) {
        return mapIn[key];
      }
    
      @override
      void set(String key, T value) {
        mapIn[key] = value;
        print("success");
      }
    }
    
    // 測試範型介面
    testGeneric() {
      Cache cacheTest = new Cache<String>();
      cacheTest.set("name", "LiXiaolong");
      print("${cacheTest.get("name")}");
    }
    複製程式碼

流程控制

  • if...else...

    bool isSelected = true;
    String userName = "LiBai";
    
    // if (userName) print(userName); // 錯誤,Dart中必須判斷bool型別
    if (isSelected) {
        print("selected")
    } else {
        print("No");
    }
    複製程式碼
  • for

    List nameList = ["1", "2", "3"];
    // for
    for (int i = 0; i < nameList.length; i++) {
      print(nameList[i]);
    }
    
    // forin (.for)
    for (var value in nameList) {
      print(value);
    }
    
    // forEach
    nameList.forEach((itemValue) => print(itemValue));
    複製程式碼
  • while

    int count = 0;
    while(count<10) {
      print("count:$count");
      count++;
    }
    複製程式碼
  • do...while

    var count = 0;
    do {
      print("count:$count");
      count++;
    } while(count<10);
    複製程式碼
  • switch case

    enum Animal {
      cat,
      dog,
      bird
    }
    
    
    testSwith(Animal animal) {
      String mark1 = "A";
      switch(mark1) {
        case 'A':
          print("A");
          break;
        case 'B':
          print("B");
          break;
      }
    
      int mark2 = 1;
      switch(mark2) {
        case 1:
          print("1");
          break;
        case 2:
          print("2");
      }
    
      switch(animal) {
        case Animal.cat:
          print("cat");
          break;
        case Animal.dog:
        case Animal.bird:
          print("dog or bird");
          break;
      }
    }
    
    
    // 測試
    testSwith(Animal.bird);
    複製程式碼
  • break 立即結束整個控制流語句的執行

    String mark1 = "A";
      switch(mark1) {
        case 'A':
          print("A");
          break;
        case 'B':
          print("B");
          break;
    }
    複製程式碼
  • continue 停止當前迴圈不再往下執行,進入下次迴圈。即“完成了當前的迴圈迭代”而沒有離開迴圈。

    List nameList = ["1", "2", "3"];
    // for
    for (int i = 0; i < nameList.length; i++) {
      if (i ==1) continue;
      print(nameList[i]);
    }
    複製程式碼

上一頁 Flutter4 函式和範型基礎
下一頁 Flutter6 包、異常、非同步和庫

相關文章