Dart abstract class mixin 究竟哪裏不一樣呢?

編程那麼多年,C,C++,OC,Swift,JS,Java都有用過。但是最新實驗了下Dart的abstract class mixin幾個關鍵字,把我弄得有點迷糊,似乎他們之間可以互相替代的,究竟他們之間有什麼不同,什麼情況使用什麼呢。

1.定義


關鍵字 作用
abstract 抽象類,在Java,C++中都是接口抽象類,可以定義屬性和虛函數,等着實現類去實現定義的方法。相當於Swift和OC的protocol,Swift裏可以使用extension實現默認方法,但是在Dart裏抽象類可以直接默認實現方法和屬性,只是不能新建實例類。
class 類,可以新建實例,可以extends,implements,Mixin
mixin 通過創建一個繼承自 Object 且沒有構造函數的類,來 實現 一個 Mixin 。 如果 Mixin 不希望作爲常規類被使用,使用關鍵字 mixin 替換 class 。

2.abstract class


在Dart中特點:

  • 不能實例化
  • 接口抽象
  • 可以默認實現方式
  • 可以被別的類實現和繼承,抽象類可以直接繼承

代碼例子說明:

2.1、abstract class 默認實現方法

需要使用 實現類 extends 之後調用,使用implements需要實現默認方法。


main(List<String> args) {
  final wp = Woman();
  final m = Man("小明");
  wp.run();
  m.run();
}

abstract class Person {
  run() {
    print("奔跑");
  }
}

class Man extends Person {

}

class Woman implements Person {
  @override
  run() {
    print("女神跑步");
  }
}

打印結果:

女神跑步
奔跑

2.2、抽象類被抽象類繼承

abstract class Person {
  Person(this.name);
  final String name;

  talk();
  run() {
    print("奔跑");
  }
}

abstract class Student extends Person {
  Student(String name) : super(name);
  int age;
  study() {
    print("學習");
  }

  hasClass();
}

class Child implements Student {
  @override
  int age;

  @override
  hasClass() {
    // TODO: implement hasClass
    throw UnimplementedError();
  }

  @override
  // TODO: implement name
  String get name => throw UnimplementedError();

  @override
  run() {
    // TODO: implement run
    throw UnimplementedError();
  }

  @override
  study() {
    // TODO: implement study
    throw UnimplementedError();
  }

  @override
  talk() {
    // TODO: implement talk
    throw UnimplementedError();
  }
 
}

總結:abstract class被abstract class繼承,繼承需要實現父類構造函數。

2.3、abstract class 被Class extends和implements的區別

abstract class Person {
  Person(this.name);
  final String name;

  talk();
  run() {
    print("奔跑");
  }
}

class Man extends Person {
  Man(String name) : super(name);

  @override
  talk() {
    print("man talk");
  }
}

class Woman implements Person {
  @override
  String get name => "女神";

  @override
  run() {
    print("女神跑步");
  }

  @override
  talk() {
    print("女神說話");
  }
}

上面例子,Man 類繼承Person 抽象類,Woman 類實現Person抽象類,可以看出區別如下:

  1. extends 自動生成abstract 的構造方法,implements則不會
  2. extends 不需要實現屬性可以直接利用父類, implements需要實現。
  3. extends 不需要實現默認方法可以直接利用,implements需要實現。(重要)
  4. 接口定義方法 extends和implements都需要實現。

3. class

Dart的Class特點: 可以當做抽象接口類被實現

代碼例子:

class Person {
  final String name;
  Person(this.name);

  talk() {
    print("person talk");
  }

  run() {
    print("person run");
  }
}

class Woman implements Person {
  @override
  // TODO: implement name
  String get name => throw UnimplementedError();

  @override
  run() {
    // TODO: implement run
    throw UnimplementedError();
  }

  @override
  talk() {
    // TODO: implement talk
    throw UnimplementedError();
  }
  
}

4. mixin

通過創建一個繼承自 Object 且沒有構造函數的類,來 實現 一個 Mixin 。 如果 Mixin 不希望作爲常規類被使用,使用關鍵字 mixin 替換 class 。

  1. mixin 沒有構造函數,不能被實例化
  2. 可以當做接口使用,class 混入之後需要實現
  3. 默認方法不需要實現(這個是和abstract 的區別)
  4. 如果一個類with,方法相同,先執行本體方法,然後按照混入順序,執行最後mixin方法。
  5. 可以使用on 指定混入的類類型,如果不是報錯。

代碼演示:

main(List<String> args) {  
  final man = Man("男神");
  man.classes();
  man.study();
}

class Person {
  final String name;
  Person(this.name);

  talk() {
    print("person talk");
  }

  run() {
    print("person run");
  }
}

class Man extends Person with Student {
  Man(String name) : super(name);

  @override
  study() {
    print("man study");
  }

  classes() {
    print("三年8班");
  }
}

mixin Student {
  int age;
  study();
  classes() {
    print("三年二班");
  }

  run() {
    print("student run");
  }
}

打印結果:

三年8班
man study

 

5. 總結


根據以上特性總結下,在工作中什麼情況,使用哪種關係結構。

主關係 方式 子關係 用途
class extends abstrct 當需要共通的構建方法和默認屬性、方法的時候,同時需要重新實現接口方法。
abstrct extends abstrct 子抽象,類似class 繼承關係。
class implements abstrct 每一個子關係都需要抽象定義所有的接口規範 ,規範類不需要實例
class implements class 每一個子關係都需要抽象定義所有的接口規範 ,規範類需要實例化
class with mixin 主關係混入子關係的內容,子關係不需要實例化
class with class 主關係混入子關係的內容,子關係需要實例化
class with on mixin 主關係混入子關係的內容,主關係必須是一個特點的類型,子關係不需要實例化
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章