### 方法
* 方法就是为对象提供行为的函数。
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);
}
~~~
* 注:考虑到使用高阶层的方法而不是静态方法,是为了常用或者广泛使用的工具和功能。
* 你可以将静态方法作为编译时常量。例如,你可以把静态方法作为一个参数传递给静态构造函数。