### 方法
* 方法就是為對象提供行為的函數。
1. ***實例方法***
* 對象的實例方法可以訪問實例變量和 this 。以下示例中的 distanceTo() 方法是實例方法的一個例子:
~~~
import 'dart:math';
class Point {
num x;
num 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);
}
}
~~~
2. ***setters 和 Getters***
* 是一種提供對方法屬性讀和寫的特殊方法。每個實例變量都有一個隱式的 getter 方法,合適的話可能還會有 setter 方法。你可以通過實現 getters 和 setters 來創建附加屬性,也就是直接使用 get 和 set 關鍵詞:
~~~
class Rectangle {
num left;
num top;
num width;
num height;
Rectangle(this.left, this.top, this.width, this.height);
// 定義兩個計算屬性: right and 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;
}
main() {
var rect = new Rectangle(3, 4, 20, 15);
assert(rect.left == 3);
rect.right = 12;
assert(rect.left == -8);
}
~~~
* 借助于 getter 和 setter ,你可以直接使用實例變量,并且在不改變客戶代碼的情況下把他們包裝成方法。
* ***注:***不論是否顯式地定義了一個 getter,類似增量(++)的操作符,都能以預期的方式工作。為了避免產生任何向著不期望的方向的影響,操作符一旦調用 getter ,就會把他的值存在臨時變量里。
3. ***抽象方法***
* Instance , getter 和 setter 方法可以是抽象的,也就是定義一個接口,但是把實現交給其他的類。要創建一個抽象方法,使用分號(;)代替方法體:
~~~
abstract class Doer {
// ...定義實例變量和方法...
void doSomething(); // 定義一個抽象方法。
}
class EffectiveDoer extends Doer {
void doSomething() {
// ...提供一個實現,所以這里的方法不是抽象的...
}
}
~~~
4. ***枚舉類型***
* 枚舉類型,通常被稱為 enumerations 或 enums ,是一種用來代表一個固定數量的常量的特殊類。
* 聲明一個枚舉類型需要使用關鍵字 enum :
~~~
enum Color {
red,
green,
blue
}
~~~
* 在枚舉中每個值都有一個 index getter 方法,它返回一個在枚舉聲明中從 0 開始的位置。例如,第一個值索引值為 0 ,第二個值索引值為 1 。
~~~
assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);
~~~
* 要得到枚舉列表的所有值,可使用枚舉的 values 常量。
~~~
```
List<Color> colors = Color.values;
assert(colors[2] == Color.blue);
```
* 你可以在 switch 語句 中使用枚舉。如果 e 在 switch (e) 是顯式類型的枚舉,那么如果你不處理所有的枚舉值將會彈出警告:
```
enum Color {
red,
green,
blue
}
// ...
Color aColor = Color.blue;
switch (aColor) {
case Color.red:
print('Red as roses!');
break;
case Color.green:
print('Green as grass!');
break;
default: // Without this, you see a WARNING.
print(aColor); // 'Color.blue'
}
```
***枚舉類型有以下限制***
* 你不能在子類中混合或實現一個枚舉。
* 你不能顯式實例化一個枚舉。
~~~
5. ***為類添加特征:mixins***
* mixins 是一種多類層次結構的類的代碼重用。
* 要使用 mixins ,在 with 關鍵字后面跟一個或多個 mixin 的名字。下面的例子顯示了兩個使用mixins的類:
~~~
class Musician extends Performer with Musical {
// ...
}
class Maestro extends Person with Musical,
Aggressive, Demented {
Maestro(String maestroName) {
name = maestroName;
canConduct = true;
}
}
~~~
* 要實現 mixin ,就創建一個繼承 Object 類的子類,不聲明任何構造函數,不調用 super 。例如:
~~~
abstract class Musical {
bool canPlayPiano = false;
bool canCompose = false;
bool canConduct = false;
void entertainMe() {
if (canPlayPiano) {
print('Playing piano');
} else if (canConduct) {
print('Waving hands');
} else {
print('Humming to self');
}
}
}
~~~
6. ***類的變量和方法***
* 使用 static 關鍵字來實現類變量和類方法。
* 只有當靜態變量被使用時才被初始化。
* 靜態變量, 靜態變量(類變量)對于類狀態和常數是有用的:
~~~
class Color {
static const red = const Color('red'); // 一個恒定的靜態變量
final String name; // 一個實例變量。
const Color(this.name); // 一個恒定的構造函數。
}
main() {
assert(Color.red.name == 'red');
}
~~~
* 靜態方法, 靜態方法(類方法)不在一個實例上進行操作,因而不必訪問 this 。例如:
~~~
import 'dart:math';
class Point {
num x;
num y;
Point(this.x, this.y);
static num distanceBetween(Point a, Point b) {
var dx = a.x - b.x;
var dy = a.y - b.y;
return sqrt(dx * dx + dy * dy);
}
}
main() {
var a = new Point(2, 2);
var b = new Point(4, 4);
var distance = Point.distanceBetween(a, b);
assert(distance < 2.9 && distance > 2.8);
}
~~~
* 注:考慮到使用高階層的方法而不是靜態方法,是為了常用或者廣泛使用的工具和功能。
* 你可以將靜態方法作為編譯時常量。例如,你可以把靜態方法作為一個參數傳遞給靜態構造函數。