Dart簡(jiǎn)介3--mixin

說(shuō)明

Dart 是不支持多繼承的,但是它支持 mixin,簡(jiǎn)單來(lái)講 mixin 可以 “組合” 多個(gè)類,這樣就極大的減少了代碼冗余。mixin是面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言中的類,提供了方法的實(shí)現(xiàn)。其他類可以訪問(wèn)mixin類的方法、變量而不必成為其子類。簡(jiǎn)而言之,mixins是普通的類,我們可以從中擴(kuò)展方法(或變量)而不擴(kuò)展類。

示例

定義一個(gè) Person 類,實(shí)現(xiàn)吃飯、說(shuō)話、走路和寫(xiě)代碼功能,同時(shí)定義一個(gè) Dog 類,實(shí)現(xiàn)吃飯、和走路功能。我們定義了幾個(gè) mixin,然后通過(guò) with 關(guān)鍵字將它們組合成不同的類。有一點(diǎn)需要注意:如果多個(gè)mixin 中有同名方法,with 時(shí),會(huì)默認(rèn)使用最后面的 mixin 的,mixin 方法中可以通過(guò) super 關(guān)鍵字調(diào)用之前 mixin 或類中的方法。

class Person {
  say() {
    print('say');
  }
}

mixin Eat {
  eat() {
    print('eat');
  }
}

mixin Walk {
  walk() {
    print('walk');
  }
}

mixin Code {
  code() {
    print('key');
  }
}

class Dog with Eat, Walk{}
class Man extends Person with Eat, Walk, Code{}

從用法有點(diǎn)類似于Java中的多接口實(shí)現(xiàn),不同點(diǎn)在于,mixin可以有默認(rèn)實(shí)現(xiàn),當(dāng)然Java8中也有了這個(gè)功能。

mixin之線性化

在上面的示例中,我們發(fā)現(xiàn)with關(guān)鍵字后有多個(gè)類。那么這里就產(chǎn)生了一個(gè)問(wèn)題——如果with后的多個(gè)類中有相同的方法,那么當(dāng)調(diào)用該方法時(shí),會(huì)調(diào)用哪個(gè)類里的方法尼?由于距離with關(guān)鍵字越遠(yuǎn)的類會(huì)重寫(xiě)前面類中的相同方法,因此分為以下兩種情況:

  • 如果當(dāng)前使用類重寫(xiě)了該方法,就會(huì)調(diào)用當(dāng)前類中的方法。
  • 如果當(dāng)前使用類沒(méi)有重寫(xiě)了該方法,則會(huì)調(diào)用距離with關(guān)鍵字最遠(yuǎn)類中的方法。
//BindingBase
abstract class BindingBase {
  void initInstances() {
    print("BindingBase——initInstances");
  }
}
//GestureBinding
mixin GestureBinding on BindingBase{
  @override
  void initInstances() {
    print("GestureBinding——initInstances");
    super.initInstances();
  }
}
//RendererBinding
mixin RendererBinding{
  @override
  void initInstances() {
    print("RendererBinding——initInstances");
    super.initInstances();
  }
}
// WidgetsBinding
mixin WidgetsBinding on BindingBase{
  @override
  void initInstances() {
    print("WidgetsBinding——initInstances");
    super.initInstances();
  }
}
//WidgetsFlutterBinding
class WidgetsFlutterBinding extends BindingBase
    with GestureBinding, RendererBinding, WidgetsBinding {
    static WidgetsBinding ensureInitialized() {
      return WidgetsFlutterBinding();
    }
}
//main
main(List<String> arguments) {
  var binding = WidgetsFlutterBinding();
  binding.initInstances();
}

WidgetsFlutterBinding中并沒(méi)有重寫(xiě)initInstances方法,那么就以最右邊重寫(xiě)該方法的類——WidgetsBinding為主。那么結(jié)果應(yīng)該如下:WidgetsBinding——initInstances
其實(shí)結(jié)果是:
WidgetsBinding——initInstances RendererBinding——initInstances GestureBinding——initInstances BindingBase——initInstances
這是為什么尼?仔細(xì)一點(diǎn)就可以發(fā)現(xiàn),我們?cè)赪idgetsBinding、RendererBinding及GestureBinding中都調(diào)用了父類的initInstances方法,也因此會(huì)一級(jí)一級(jí)往上調(diào)用。如果我們?nèi)∠摼浯a,則會(huì)終止這種調(diào)用方式。這就是線性化。

先就寫(xiě)這么多,下面就得邊學(xué)習(xí)邊總結(jié),有什么不對(duì)的地方,歡迎留言討論,謝謝!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、flutter啟動(dòng)流程1.實(shí)例化WidgetsFlutterBinding類,2.創(chuàng)建組件樹(shù)attachRoo...
    齊玉婷閱讀 3,202評(píng)論 0 9
  • 在開(kāi)始閱讀此篇文章之前,我們可以先思考下如下問(wèn)題: 1.什么是 Mixin ?2.Mixin為什么會(huì)被設(shè)計(jì)出來(lái),它...
    quteng閱讀 896評(píng)論 0 0
  • 假設(shè)我們需要實(shí)現(xiàn)一個(gè)動(dòng)物世界的功能。Animal作為基類派生出哺乳類、鳥(niǎo)類、魚(yú)類三種類型,各個(gè)類型又能派生出具體的...
    嘉偉咯閱讀 990評(píng)論 0 1
  • 前言 假如Dart不存在Mixin關(guān)鍵字,并且有幾個(gè)不存在繼承關(guān)系的類,他們有相同的代碼,那么該如何復(fù)用這些相同的...
    brock閱讀 1,608評(píng)論 0 0
  • 一、概念“Mixins are a way of reusing a class’s code in multip...
    wtm007閱讀 2,163評(píng)論 0 5

友情鏈接更多精彩內(nèi)容