dart class overview

寫在前面

最近在折騰 flutter 相關的東西,因此固然要擼一下 dart 了。編程語言這個東西,接觸得多了學習起來速度會提高很多,可是不一樣的語言具備不一樣的特點,咱們須要花一些時間去關注它們的賣點,並且對於大部分面嚮對象語言,也須要格外注意的概念,所以專門花了一些時間結合官方文檔整理學習 dart 中關於類的內容。java

dart 是一門面向對象的語言,既然是面向對象就不會缺乏類(class)這個概念。dart 中的 classes 包含的內容繁多,可是若是你同時擁有使用靜態語言和動態語言的經驗則會容易很多。python

Note: 示例代碼中包含一些 dart 的基本語法,建議閱讀以前先進行了解。若是有 typescript 或者 java 使用經驗的話,應該會很熟悉。

聲明、實例化及訪問屬性

這一部分是最基本的內容,和大部分編程語言的語法差很少。好比想要聲明一個 Point 類:typescript

class Point {
  num x, y = 1;

  Point(num x, num y) {
    this.x = x;
    this.y = y;
  }

  Point.fromJson(Map<String, num> json){
    this.x = json['x'];
    this.y = json['y'];
  }
  /* 相似 typescript 可使用以下的語法糖
  Point(this.x, this.y);
  */
}

實例化:

Point p = Point(1, 1); // 或者 new Point(1, 1)

訪問屬性:

print('${p.x} ${p.y}'); // 類的方法同理

還可使用 ?. 來避免當訪問實例爲空時拋出異常:編程

print('${p?.x}');

屬性可見範圍

dart 中不存在相似 java 和 typescript 中的 private、protected、public 修飾符,它使用約定來對類屬性的可見範圍進行控制。約定以下:
若是一個標識符如下劃線(_)開頭,則它爲一個私有標識符。json

構造函數

dart 類的構造函數存在兩種形式,一種爲 ClassName() ,另外一種是 ClassName.ConstructorName() ,舉例說明:設計模式

var p1 = new Point(2, 2);
var p2 = new Point.fromJson({'x': 1, 'y': 2});

這裏的 fromJson 是一個自定義的構造器方法,在 dart 中它叫作 Named constructors,因此上面的 Point 類也能夠這麼聲明:編程語言

class Point {
  num x, y = 1;

  Point(num x, num y) {
    this.x = x;
    this.y = y;
  }

  Point.fromJson(Map<String, num> json){
    this.x = json['x'];
    this.y = json['y'];
  }
}

在 dart 的構造器中還涉及一個東西,叫做 initializer list。大致的語法以下:ide

class Point {
  ...(略)

  Point.fromJson(Map<String, num> json): x = json['x'],y = json['y'];
}

這種寫法和上面的代碼是等價的。關於 initializer list 語法能夠參考這裏函數

除了基本的構造器之外,dart 還能夠聲明其餘類型的構造器,當前有三種:學習

關於具體的語法能夠參考連接所指向的官方文檔,我覺的比較有用的應當是工廠構造器。由於在面向對象編程中,一個基本的設計模式便是工廠模式,dart 提供的工廠構造器能夠說是在語法層面原生提供工廠模式的實現方式。

最後關於構造器還有一點值得一說,就是當存在繼承關係並在默認狀況下,構造器的調用順序以下:
initializer list -> 父類默認無參構造器 -> 主類默認無參構造器

若是父類不存在默認無參構造器,那麼主類必須顯式地調用父類的其餘構造器(Named constructors 或者 有參構造器),調用的代碼能夠包含在 initializer list 中,以下:

class Employee extends Person {
  Employee(Map data) : super(data);
}

方法

類的方法能夠劃分爲如下幾類:

接口

不像 java,dart 中每個類都會隱式的聲明一個包含當前類及它所實現全部接口的成員屬性的接口。如今咱們想實現一個能夠 run 和 jump 的 Person 類,代碼以下:

class Run {
  void run() {}
}

class Jump {
  void jump() {}
}

class Person implements Run, Jump {
  void run() {
    print('I can run');
  }
  
  void jump() {
    print('I can jump');
  }
}

繼承

和其餘面向對象編程語言中的繼承差很少,能夠參考這裏

枚舉

dart 中也能夠像 typescript 同樣,使用 enum 聲明枚舉對象,以下:

enum Color { red, green, blue }

枚舉相比類有以下限制:
沒法繼承或者使用 mixin,同時也沒法被當作接口
沒法顯示實例化

mixins

熟悉 python 的話會很熟悉這個特性,dart 中使用 with 關鍵字來在一個類中混入 mixins,好比:

class Musician extends Performer with Musical {
  // ···
}

聲明一個 mixin 的語法很簡單,首先創造一個抽象類,同時不要聲明構造器,以下:

abstract class Musical {
  bool canPlayPiano = false;
  bool canCompose = false;
  bool canConduct = false;

  void entertainMe() {
    ...(作一些事)
  }
}

靜態屬性及方法

和其餘編程語言相似,只須要在屬性或者方法前加 static 關鍵字便可。

抽象類

和其餘編程語言相似,經過 abstract 關鍵字聲明,好比:

abstract class AbstractContainer {
  void updateChildren(); // Abstract method.
}

抽象類沒法實例化,除非它被實現。

Callable

類能夠提供一個 call() 方法以使當前類成爲 Callable class,提供該方法之後類實例能夠被當作函數來調用,好比:

class Point {
  ...(略)

  call() => '${this.x} ${this.y}';
}

直接調用類實例來輸出座標:

var p1 = new Point(1, 2);
p1(); // 1 2
相關文章
相關標籤/搜索