Dart_基礎(chǔ)_類

Dart 只能單繼承参淫,但是可以多層繼承制市。

調(diào)用成員變量

操作符幾乎和別的語言類似示损,提個比較特殊的賦值操作符 ??= 和 ?.操作符:

var a = 1;
var b;
b ?? = a; // 如果 b 的值是 null 則將 a 賦值給 b朗和,否則保持不變
var c = size?.x; // 如果 size 為 null 則返回 null馁痴,否則返回 size.a 的值

構(gòu)造函數(shù)

使用

通過 構(gòu)造函數(shù) 創(chuàng)建對象谊娇。 構(gòu)造函數(shù)的名字可以是 *ClassName* 或者 *ClassName*.*identifier*。例如罗晕, 以下代碼使用 a 和 a.instance() 構(gòu)造函數(shù)創(chuàng)建 Point 對象:

var a1 = a(2, 2);
var a2 = a.instance({'x': 1, 'y': 2});
//在 Dart 2 中 new 關(guān)鍵字變成了可選的济欢。
var a1 = new a(2, 2);
var a2 = new a.instance({'x': 1, 'y': 2});

常量構(gòu)造函數(shù)

var a = const ImmutablePoint(1, 1);
var b = const ImmutablePoint(1, 1);

assert(identical(a, b)); // 它們是同一個實例赠堵。

常量上下文 中, 構(gòu)造函數(shù)或者字面量前的 const 可以省略法褥。 例如茫叭,下面代碼創(chuàng)建了一個 const 類型的 map 對象:

// 這里有很多的 const 關(guān)鍵字。
const pointAndLine = const {
  'point': const [const ImmutablePoint(0, 0)],
  'line': const [const ImmutablePoint(1, 10), const ImmutablePoint(-2, 11)],
};

// 僅有一個 const 半等,由該 const 建立常量上下文揍愁。
const pointAndLine = {
  'point': [ImmutablePoint(0, 0)],
  'line': [ImmutablePoint(1, 10), ImmutablePoint(-2, 11)],
};
/**************************************************************************/
var a = const ImmutablePoint(1, 1); // 創(chuàng)建一個常量對象
var b = ImmutablePoint(1, 1); // 創(chuàng)建一個非常量對象

assert(!identical(a, b)); // 兩者不是同一個實例!

構(gòu)造函數(shù)

class Point {
  num x, y;

  Point(num x, num y) {
    // 還有更好的方式來實現(xiàn)下面代碼,敬請關(guān)注杀饵。
    this.x = x;
    this.y = y;
  }
}
//兩種創(chuàng)建方式一樣
class Point {
  num x, y;

  // 在構(gòu)造函數(shù)體執(zhí)行前吗垮,
  // 語法糖已經(jīng)設(shè)置了變量 x 和 y。
  Point(this.x, this.y);
}

默認構(gòu)造函數(shù)

默認構(gòu)造函數(shù)沒有參數(shù)并會調(diào)用父類的無參構(gòu)造函數(shù)凹髓。

構(gòu)造函數(shù)不被繼承

子類不會繼承父類的構(gòu)造函數(shù)烁登。 子類不聲明構(gòu)造函數(shù),那么它就只有默認構(gòu)造函數(shù) (匿名蔚舀,沒有參數(shù)) 饵沧。

命名構(gòu)造函數(shù)

一個類可以實現(xiàn)多個構(gòu)造函數(shù):

class Point {
  num x, y;

  Point(this.x, this.y);

  // 命名構(gòu)造函數(shù)
  Point.origin() {
    x = 0;
    y = 0;
  }
}

切記,構(gòu)造函數(shù)不能夠被繼承赌躺, 這意味著父類的命名構(gòu)造函數(shù)不會被子類繼承狼牺。 如果希望使用父類中定義的命名構(gòu)造函數(shù)創(chuàng)建子類, 就必須在子類中實現(xiàn)該構(gòu)造函數(shù)礼患。

初始化列表

// 在構(gòu)造函數(shù)體執(zhí)行之前是钥,
// 通過初始列表設(shè)置實例變量。
Point.fromJson(Map<String, num> json)
    : x = json['x'],
      y = json['y'] {
  print('In Point.fromJson(): ($x, $y)');
}

Point.withAssert(this.x, this.y) : assert(x >= 0) {
  print('In Point.withAssert(): ($x, $y)');
}

警告: 初始化程序的右側(cè)無法訪問 this 缅叠。

重定向構(gòu)造函數(shù)

class Point {
  num x, y;

  // 類的主構(gòu)造函數(shù)悄泥。
  Point(this.x, this.y);

  // 指向主構(gòu)造函數(shù)
  Point.alongXAxis(num x) : this(x, 0);
}

常量構(gòu)造函數(shù)

class ImmutablePoint {
  static final ImmutablePoint origin =
      const ImmutablePoint(0, 0);

  final num x, y;

  const ImmutablePoint(this.x, this.y);
}

工廠構(gòu)造函數(shù)

當執(zhí)行構(gòu)造函數(shù)并不總是創(chuàng)建這個類的一個新實例時,則使用 factory 關(guān)鍵字肤粱。 例如弹囚,一個工廠構(gòu)造函數(shù)可能會返回一個 cache 中的實例, 或者可能返回一個子類的實例领曼。

class Logger {
  final String name;
  bool mute = false;

  // 從命名的 _ 可以知鸥鹉,
  // _cache 是私有屬性。
  static final Map<String, Logger> _cache =
      <String, Logger>{};

  factory Logger(String name) {
    if (_cache.containsKey(name)) {
      return _cache[name];
    } else {
      final logger = Logger._internal(name);
      _cache[name] = logger;
      return logger;
    }
  }

  Logger._internal(this.name);

  void log(String msg) {
    if (!mute) print(msg);
  }
}
//工廠構(gòu)造函的調(diào)用方式與其他構(gòu)造函數(shù)一樣:
var logger = Logger('UI');
logger.log('Button clicked');

提示: 工廠構(gòu)造函數(shù)無法訪問 this庶骄。

獲取對象的類型

使用對象的 runtimeType 屬性毁渗, 可以在運行時獲取對象的類型, runtimeType 屬性回返回一個 Type 對象单刁。

實例變量

class Point {
  num x; // 聲明示例變量 x灸异,初始值為 null 。
  num y; // 聲明示例變量 y,初始值為 null 绎狭。
  num z = 0; // 聲明示例變量 z细溅,初始值為 0 。
}

所有實例變量都生成隱式 getter 方法儡嘶。 非 final 的實例變量同樣會生成隱式 setter 方法喇聊。

方法

實例方法

import 'dart:math';

class Point {
  num x, y;

  Point(this.x, this.y);

  num distanceTo(Point other) {
    var dx = x - other.x;
    var dy = y - other.y;
    return sqrt(dx * dx + dy * dy);
  }
}

Getter 和 Setter

Dart 會為變量提供隱形 Getter 和 Setter ,但是也可以使用 getset 關(guān)鍵字實現(xiàn) Getter 和 Setter :

class Rectangle {
  num left, top, width, height;

  Rectangle(this.left, this.top, this.width, this.height);

  // 定義兩個計算屬性: right 和 bottom蹦狂。
  num get right => left + width;
  set right(num value) => left = value - width;
  num get bottom => top + height;
  set bottom(num value) => top = value - height;
}

void main() {
  var rect = Rectangle(3, 4, 20, 15);
  assert(rect.left == 3);
  rect.right = 12;
  assert(rect.left == -8);
}

提示: 類似 (++) 之類操作符不管是否定義了 getter 方法誓篱,都能夠正確的執(zhí)行。 為了避免一些問題凯楔,操作符只調(diào)用一次 getter 方法窜骄, 然后把值保存到一個臨時的變量中。

抽象方法

同 Java 中的實現(xiàn):

abstract class Doer {
  // 定義實例變量和方法 ...

  void doSomething(); // 定義一個抽象方法摆屯。
}

class EffectiveDoer extends Doer {
  void doSomething() {
    // 提供方法實現(xiàn)邻遏,所以這里的方法就不是抽象方法了...
  }
}

抽象類

使用 abstract 修飾符來定義 抽象類 — 抽象類不能實例化。 抽象類通常用來定義接口虐骑,以及部分實現(xiàn)准验。 如果希望抽象類能夠被實例化,那么可以通過定義一個 工廠構(gòu)造函數(shù) 來實現(xiàn)廷没。

// 這個類被定義為抽象類糊饱,
// 所以不能被實例化。
abstract class AbstractContainer {
  // 定義構(gòu)造行數(shù)颠黎,字段另锋,方法...

  void updateChildren(); // 抽象方法。
}

隱式接口

同 Java 中的接口:

// person 類狭归。 隱式接口里面包含了 greet() 方法聲明夭坪。
class Person {
  // 包含在接口里,但只在當前庫中可見唉铜。
  final _name;

  // 不包含在接口里台舱,因為這是一個構(gòu)造函數(shù)律杠。
  Person(this._name);

  // 包含在接口里潭流。
  String greet(String who) => 'Hello, $who. I am $_name.';
}

// person 接口的實現(xiàn)。
class Impostor implements Person {
  get _name => '';

  String greet(String who) => 'Hi $who. Do you know who I am?';
}

String greetBob(Person person) => person.greet('Bob');

void main() {
  print(greetBob(Person('Kathy')));
  print(greetBob(Impostor()));
}

//實現(xiàn)多接口
class Point implements Comparable, Location {...}

擴展類(繼承)

同 Java :

class Television {
  void turnOn() {
    _illuminateDisplay();
    _activateIrSensor();
  }
  // ···
}

class SmartTelevision extends Television {
  void turnOn() {
    super.turnOn();
    _bootNetworkInterface();
    _initializeMemory();
    _upgradeApps();
  }
  // ···
}

重寫類成員

同 Java:

class SmartTelevision extends Television {
  @override
  void turnOn() {...}
  // ···
}

重寫運算符

這個就很神器柜去,用代碼來說明吧灰嫉,下面示例演示一個類重寫 +- 操作符

class Vector {
  final int x, y;

  Vector(this.x, this.y);

  Vector operator +(Vector v) => Vector(x + v.x, y + v.y);
  Vector operator -(Vector v) => Vector(x - v.x, y - v.y);

  // 運算符 == 和 hashCode 部分沒有列出。 有關(guān)詳情嗓奢,請參考下面的注釋讼撒。
  // ···
}

void main() {
  final v = Vector(2, 3);
  final w = Vector(2, 2);

  assert(v + w == Vector(4, 5));
  assert(v - w == Vector(0, 1));
}

可被重寫的運算符

| < | + | | | [] |
| ---- | ---- | ---- | ----- |
| > | / | ^ | []= |
| <= | ~/ | & | ~ |
| >= | * | << | == |
| | % | >> | |

提示: 你可能會被提示 != 運算符為非可重載運算符。 因為 e1 != e2 表達式僅僅是 !(e1 == e2) 的語法糖。

noSuchMethod()

當代碼嘗試使用不存在的方法或?qū)嵗兞繒r根盒, 通過重寫 noSuchMethod() 方法钳幅,來實現(xiàn)檢測和應對處理:

class A {
  // 如果不重寫 noSuchMethod,訪問
  // 不存在的實例變量時會導致 NoSuchMethodError 錯誤炎滞。
  @override
  void noSuchMethod(Invocation invocation) {
    print('You tried to use a non-existent member: ' +
        '${invocation.memberName}');
  }
}

枚舉類型

同 Java:

enum Color { red, green, blue }
//枚舉中存在一個值 index 返回值為枚舉類型定義中的位置 
assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);
//使用 values  獲取所有枚舉值列表( list )
List<Color> colors = Color.values;
assert(colors[2] == Color.blue);
//可以在 switch 語句 中使用枚舉
var aColor = Color.blue;
switch (aColor) {
  case Color.red:
    print('Red as roses!');
    break;
  case Color.green:
    print('Green as grass!');
    break;
  default: // 沒有這個敢艰,會看到一個警告。
    print(aColor); // 'Color.blue'
}

混入(Mixin)

這個理解起來不算難册赛,我們寫一個例子:

class S {
  a() {print("S.a");}
}

class A {
  a(){print("A.a");}
  b(){print("A.b");}
}

class B {
  a(){print("B.a");}
  b(){print("B.b");}
  c(){print("B.c ");}
}

class T = B with A, S;

main(List<String> args) {
  T t = new T();
  t.a();
  t.b();
  t.c();
}

//輸出
S.a
A.b
B.c 

靜態(tài)

Dart 和 Java 中的靜態(tài)是一樣的钠导;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市森瘪,隨后出現(xiàn)的幾起案子牡属,更是在濱河造成了極大的恐慌,老刑警劉巖扼睬,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逮栅,死亡現(xiàn)場離奇詭異,居然都是意外死亡窗宇,警方通過查閱死者的電腦和手機证芭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來担映,“玉大人废士,你說我怎么就攤上這事∮辏” “怎么了官硝?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長短蜕。 經(jīng)常有香客問我氢架,道長,這世上最難降的妖魔是什么朋魔? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任岖研,我火速辦了婚禮,結(jié)果婚禮上警检,老公的妹妹穿的比我還像新娘孙援。我一直安慰自己,他們只是感情好扇雕,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布拓售。 她就那樣靜靜地躺著,像睡著了一般镶奉。 火紅的嫁衣襯著肌膚如雪础淤。 梳的紋絲不亂的頭發(fā)上崭放,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音鸽凶,去河邊找鬼币砂。 笑死,一個胖子當著我的面吹牛玻侥,可吹牛的內(nèi)容都是我干的道伟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼使碾,長吁一口氣:“原來是場噩夢啊……” “哼蜜徽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起票摇,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤拘鞋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后矢门,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盆色,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年祟剔,在試婚紗的時候發(fā)現(xiàn)自己被綠了隔躲。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡物延,死狀恐怖宣旱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情叛薯,我是刑警寧澤浑吟,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站耗溜,受9級特大地震影響组力,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜抖拴,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一燎字、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧阿宅,春花似錦候衍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至拉馋,卻和暖如春榨为,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背煌茴。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工随闺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蔓腐。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓矩乐,卻偏偏與公主長得像,于是被迫代替她去往敵國和親回论。 傳聞我的和親對象是個殘疾皇子散罕,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

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

  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學習記錄文檔,今天18年5月份再次想寫文章傀蓉,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 2,752評論 2 9
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 3,801評論 1 10
  • 面向?qū)ο缶幊蹋∣OP) 在前面的章節(jié)中葬燎,我們學習了Kotlin的語言基礎(chǔ)知識误甚、類型系統(tǒng)、集合類以及泛型相關(guān)的知識谱净。...
    Tenderness4閱讀 4,438評論 1 6
  • 下標腳本 下標腳本 可以定義在類窑邦、結(jié)構(gòu)體和枚舉這些目標中,可以認為是訪問集合(collection)壕探,列表(li...
    cht005288閱讀 448評論 0 0
  • ??面向?qū)ο螅∣bject-Oriented李请,OO)的語言有一個標志派继,那就是它們都有類的概念,而通過類可以創(chuàng)建任意...
    霜天曉閱讀 2,107評論 0 6