Dart語言學(xué)習(xí)筆記(二)類型系統(tǒng)

啰啰嗦嗦的前言

軟件發(fā)展的歷史印證了應(yīng)用層開發(fā)必然是OOP(Object Oriented Programming)(面向?qū)ο缶幊陶Z言)語言的天下,安卓應(yīng)用開發(fā)之前一直是使用jvm系語言(最開始是java,后來又有kotlin)翘地,但是java由于需要兼顧全平臺(tái),很多地方并不是為移動(dòng)端量身定做迫悠,這就導(dǎo)致了某些方面無法做到最優(yōu)携添,再加上java易主后oracle跟谷歌在版權(quán)問題上的各種不愉快,可能就導(dǎo)致了谷歌想降低安卓平臺(tái)對(duì)java的依賴叛本,后來就有了flutter沪蓬,flutter使用dart語言。
扯遠(yuǎn)了炮赦,關(guān)鍵字只有OOP,相比java样勃,dart是更徹底的OOP吠勘,一切都是對(duì)象性芬。那么就從類和對(duì)象學(xué)起。

類的定義

寫法跟JVM系語言都差不多剧防,隨便寫一個(gè):

abstract class Animal{
  //普通構(gòu)造器
  Animal(String name, int age):
      assert(name != null),
      assert(age > -1),
      this.name = name, this.age = age{
      print("Animal's constructor is invoked");
  }
  //命名構(gòu)造器的轉(zhuǎn)發(fā)寫法植锉,調(diào)用自己的其他構(gòu)造器
  //注意一旦這么寫了,后面就不能接函數(shù)體了
  Animal.fromMap(Map map):
        this(map["name"] ?? "unknownAnimal", map["age"] ?? 0);
  //命名構(gòu)造器的非轉(zhuǎn)發(fā)寫法峭拘,可以接函數(shù)體
  Animal.fromDynamic(dynamic object){
    this.name = object.name;
    this.age = object.age;
  }
  String name;
  int age;
  //來個(gè)抽象方法俊庇,這里不寫abstract,沒有方法體的方法就是抽象方法鸡挠。
  //動(dòng)物當(dāng)然得會(huì)動(dòng)才行
  void move();
}

上面的普通構(gòu)造器其實(shí)可以簡化辉饱,變成這樣:

  Animal(this.name, this.age):
      assert(name != null),
      assert(age > -1){
      print("Animal's constructor is invoked");
  }

這種寫法的含義是,構(gòu)造器接受兩個(gè)跟自己的域成員類型一致的變量拣展,分別賦值給它們彭沼,因?yàn)槲覀兌x的name是String,age是int备埃,所以這里就需要第一個(gè)參數(shù)是String而第二個(gè)參數(shù)是int姓惑,assert語句會(huì)在賦值之前被執(zhí)行。
注意:普通構(gòu)造器的名字跟類名相同按脚,而且每個(gè)類只能有一個(gè)普通構(gòu)造器于毙。
下面這種寫法用來讓所有對(duì)構(gòu)造器的調(diào)用都產(chǎn)生相同的對(duì)象:

class Planet{
  static String description = "這是一個(gè)行星,一旦命名就不會(huì)改名";
  static int orbitInvokedCount;
  final String name;
  const Planet(this.name);
  void showOrbit(){
    print("本來應(yīng)該讓你看到我運(yùn)行的軌道辅搬,但想想還是算了");
    print("算上你唯沮,一共${++orbitInvokedCount}個(gè)傻帽被我氣的發(fā)飆");
  }
}

如果這么寫,類里面所有非靜態(tài)成員都必須是final伞辛。這種類也是可以被繼承的烂翰。

繼承(extends)

隨便寫個(gè)子類:

class Rabbit extends Animal{
  Rabbit(String name, int age) : super(name, age);
  @override
  void move() {
    print("兔子蹦蹦跳跳的往前走");
  }
}

一個(gè)類如果不顯示指定構(gòu)造器,那么它就有一個(gè)無參的普通構(gòu)造器蚤氏,如果指定了有參構(gòu)造器甘耿,子類就必須在它和其他命名構(gòu)造器里選擇一個(gè)實(shí)現(xiàn)(如果有命名構(gòu)造器),以上例子我選擇了實(shí)現(xiàn)普通構(gòu)造器竿滨,當(dāng)然也可以實(shí)現(xiàn)命名構(gòu)造器:

class Rabbit extends Animal{
  Rabbit.fromMapToo(Map map) : super.fromMap(map);
  @override
  void move() {
    print("兔子蹦蹦跳跳的往前走");
  }
}

可以看到佳恬,命名構(gòu)造器不一定要跟父類同名,簡單來說于游,有辦法能把這個(gè)類實(shí)例化就行毁葱。不管是普通構(gòu)造器還是什么途徑都行。

實(shí)現(xiàn)(implements)

注意:在dart里贰剥,一個(gè)類在定義的時(shí)候就同時(shí)產(chǎn)生了兩個(gè)東西倾剿,一個(gè)是你寫的完整定義以及行為,另一個(gè)是由他們抽象出來的接口,也就是說前痘,當(dāng)我定義了兔子類的時(shí)候凛捏,這個(gè)東西就同時(shí)代表兩個(gè)概念:兔子這個(gè)類和像兔子的這個(gè)接口,它們的名字都是Rabbit芹缔。跟java不同坯癣,這里類的屬性也是接口的一部分,估計(jì)“得益于”getter最欠、setter語法糖示罗。。芝硬。(無奈臉)

class RabbitDoll implements Rabbit{
  @override
  int age = 0;

  @override
  String name = "兔子娃娃";
  //這個(gè)類的構(gòu)造函數(shù)不受Rabbit的約束
  RabbitDoll(this.age, this.name);
  RabbitDoll.fromWhat();

  @override
  void move() {
    print("兔子布偶不會(huì)走");
  }
}

混合(mixin)

混合的概念是把類的方法放入另一個(gè)類蚜点,這在jvm語言上應(yīng)該是以組合的形式實(shí)現(xiàn)的,dart具體實(shí)現(xiàn)方式不明吵取,上代碼說明:

class Flyable{
  String trait = "會(huì)飛";
  void move(){
    print("老子會(huì)飛");
  }
  void showTrait(){
    print("這個(gè)東西的特征是$trait");
  }
}
class Sparrow with Flyable implements Animal{
  @override
  int age;
  @override
  String name;
}
class Dove extends Animal with Flyable{
  Dove(String name, int age) : super(name, age);
}

之前定義的animal類有一個(gè)抽象方法move禽额,這個(gè)方法已經(jīng)被Flyable實(shí)現(xiàn),下面的Sparrow和Dove類分別以implements和extends的方式獲得Animal的接口特征皮官,具體實(shí)現(xiàn)都委托給被混入的Flyable了脯倒。
Dart的類型系統(tǒng)里是單繼承多實(shí)現(xiàn)捺氢、多混合藻丢,凡是帶“多”的都是逗號(hào)分隔,這就勢(shì)必考慮到一個(gè)問題那就是沖突問題摄乒,implements里不存在具體實(shí)現(xiàn)所以沒有沖突問題悠反,而多mixin的情況由于mixin類都有具體實(shí)現(xiàn),如果一個(gè)特征相同的方法在多個(gè)mixin里都有實(shí)現(xiàn)那會(huì)如何馍佑?實(shí)驗(yàn)證明斋否,寫在后面的mixin會(huì)覆蓋前面的實(shí)現(xiàn)。你調(diào)用這個(gè)方法時(shí)以最后的mixin為準(zhǔn)拭荤,當(dāng)然茵臭,前提是你方法體里不再次覆蓋這個(gè)方法。而mixin的優(yōu)先級(jí)又是高于父類實(shí)現(xiàn)的舅世。
一句話總結(jié):方法的優(yōu)先級(jí):自己的 > mixin列表[n]的 > mixin列表[0]的 > 父類的旦委。一旦沖突,優(yōu)先級(jí)低的就被覆蓋掉雏亚。
mixin其實(shí)還有一個(gè)寫法缨硝,是用mixin關(guān)鍵字定義:

mixin AnimalLike implements Animal{
  
}

這種寫法跟class的區(qū)別是:無法被實(shí)例化,不能extends其他類罢低,只能implements接口查辩,可以包含抽象成員。它可以使用on關(guān)鍵字限定只有特定類(及其子類)能混合它:

mixin AnimalLike on Dove implements Animal{
}

如果這么寫了,只有Dove和Dove的子類可以with它宜岛,當(dāng)然匀钧,on關(guān)鍵字后面是可以跟多個(gè)類的,用逗號(hào)分隔谬返。
注意:這里說的是子類而不是接口,如果你用on限定了一個(gè)類日杈,類X implements了它遣铝,那X是沒法with這個(gè)mixin的。

一個(gè)類繼承A混合了BCD莉擒,它的類型到底是什么酿炸?

這個(gè)問題其實(shí)沒什么意義,之前說過涨冀,dart在聲明一個(gè)類的時(shí)候就同時(shí)產(chǎn)生了同名的接口填硕,而無論是is操作符(對(duì)應(yīng)java的instanceof)還是泛型,里面寫的其實(shí)都是上述的同名接口鹿鳖,我們?cè)谑褂眠@些對(duì)象時(shí)關(guān)心的也只是它的方法特征(輸入輸出)而不是具體實(shí)現(xiàn)扁眯。
但如果硬要說的話,按java里那種父類的概念翅帜,子類的構(gòu)造器要追隨父類這倒是沒錯(cuò)的姻檀。

  var sparrow = Sparrow();
  var dove = Dove("鴿子", 1);
  sparrow.move();
  sparrow.showTrait();
  var animals = List<Animal>();
  var flyables = List<Flyable>();
  animals.add(sparrow);
  flyables.add(sparrow);
  animals.add(dove);
  flyables.add(dove);

dove和sparrow既是Animal也是Flyable,不同的場(chǎng)景關(guān)注點(diǎn)不同涝滴,我們想聯(lián)系一個(gè)朋友绣版,那么微信和電話都能實(shí)現(xiàn)這個(gè)功能,這里我們就只關(guān)注通訊這個(gè)功能歼疮,至于微信還能做什么其他的杂抽,在這個(gè)應(yīng)用場(chǎng)景就被忽略了。

訪問限定修飾符

在dart里以_開頭的是私有成員韩脏,跟es6一樣缩麸,沒什么好說的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末骤素,一起剝皮案震驚了整個(gè)濱河市匙睹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌济竹,老刑警劉巖痕檬,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異送浊,居然都是意外死亡梦谜,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來唁桩,“玉大人闭树,你說我怎么就攤上這事』脑瑁” “怎么了报辱?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長单山。 經(jīng)常有香客問我碍现,道長,這世上最難降的妖魔是什么米奸? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任昼接,我火速辦了婚禮,結(jié)果婚禮上悴晰,老公的妹妹穿的比我還像新娘慢睡。我一直安慰自己,他們只是感情好铡溪,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布漂辐。 她就那樣靜靜地躺著,像睡著了一般棕硫。 火紅的嫁衣襯著肌膚如雪者吁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天饲帅,我揣著相機(jī)與錄音复凳,去河邊找鬼。 笑死灶泵,一個(gè)胖子當(dāng)著我的面吹牛育八,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赦邻,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼髓棋,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了惶洲?” 一聲冷哼從身側(cè)響起按声,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎恬吕,沒想到半個(gè)月后签则,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡铐料,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年渐裂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了豺旬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡柒凉,死狀恐怖族阅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情膝捞,我是刑警寧澤坦刀,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站蔬咬,受9級(jí)特大地震影響求泰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜计盒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望芽丹。 院中可真熱鬧北启,春花似錦、人聲如沸拔第。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蚊俺。三九已至懈涛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泳猬,已是汗流浹背批钠。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留得封,地道東北人埋心。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像忙上,于是被迫代替她去往敵國和親拷呆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • Flutter日漸火爆疫粥,因此在進(jìn)行Flutter學(xué)習(xí)前先學(xué)習(xí)一些其所使用的開發(fā)語言dart的基礎(chǔ)茬斧,這篇文章主要學(xué)習(xí)...
    Samlss閱讀 10,926評(píng)論 2 28
  • Dart 語言系列 Dart 語言入門 (一) Dart 語言入門 (二) Dart 語言入門 (三) Dart ...
    mark666閱讀 1,688評(píng)論 2 8
  • Dart語言是使用flutter框架開發(fā)時(shí)候必備的語言,flutter是一個(gè)跨平臺(tái)的框架梗逮,一套代碼就可以完美實(shí)現(xiàn)安...
    礪劍鋒成閱讀 898評(píng)論 0 1
  • 此文章是v1.0+時(shí)編寫项秉,年代久遠(yuǎn),小心有毒慷彤,謹(jǐn)慎食用;锖d毯痢! 一些重要概念 所有的東西都是對(duì)象贷屎,所有的對(duì)象都是類的...
    soojade閱讀 10,051評(píng)論 2 27
  • 我要種一顆橄欖樹 就在那條你每天必經(jīng)的小路 守住了黃昏罢防,守住了夜晚 直到它開花結(jié)果 直到你從它的身邊路過 夏日的涼...
    洛風(fēng)閱讀 945評(píng)論 0 1