Skip to main content

Dart Class

Class

Dart 是 OOP 語言,這意味著 classobject 是 Dart 的根基。
類(class)是組織和封裝程式碼的基本結構。每個物件都是一個類的實例,而類則定義了物件的行為和屬性。
類可以包含方法(functions)和實例變數(instance variables),方法用於定義物件的操作,而實例變數用於存儲物件的狀態。

Instance variables (實例變數)

class Point {
double? x; // Declare instance variable x, initially null.
double? y; // Declare y, initially null.
double z = 0; // Declare z, initially 0.
}

void main() {
var point = Point();
point.x = 4; // Use the setter method for x.
assert(point.x == 4); // Use the getter method for x.
assert(point.y == null); // Values default to null.
}
warning

this 指向性

double initialX = 1.5;

class Point {
// OK, can access declarations that do not depend on `this`:
double? x = initialX;

// ERROR, can't access `this` in non-`late` initializer:
double? y = this.x;

// OK, can access `this` in `late` initializer:
late double? z = this.x;

// OK, `this.x` and `this.y` are parameter declarations, not expressions:
Point(this.x, this.y);
}

Using class members

使用點運算符 . 可以訪問物件的實例變數和方法:

// p 是一個 Point 物件,有兩個實例變數 x 和 y
var p = Point(2, 2);

// p.y 就是獲取 p 物件的 y 實例變數的值
assert(p.y == 2);

// 在 p 物件上調用 distanceTo() 方法,並傳遞一個新的 Point 物件作為參數
double distance = p.distanceTo(Point(4, 4));
tip

使用 ? 來安全訪問:

var a = p?.y;

Using constructors

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

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

// create a compile-time constant using a constant constructor
var p = const ImmutablePoint(2, 2);

Getting an object's type

使用 runtimeType 來獲得物件的 class:

print('The type of a is ${a.runtimeType}');

Implicit interfaces

在 Dart 中,每個類自動地有一個隱藏的介面,這個介面包括了這個類的所有方法和屬性。
我們可以通過實現這個介面來讓其他類擁有這些方法和屬性,而不需要繼承這個類。

  1. 先定義一個 class Person
class Person {
final String _name;

Person(this._name);

String greet(String who) => 'Hello, $who. I am $_name.';
}
  1. 再定義一個 class Impostor
class Impostor implements Person {
String get _name => '';

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

Impostor class 聲明它實現了 Person class(或者更準確地說,實現了 Person 的隱式介面),此外它實現:

  • greet 方法,但這裡的行為與 Person 的 greet 方法不同。
  • 定義了一個 _name 的 getter,但這裡 _name 返回一個空字串。
  1. 宣告一個函式 greetBob,這個函式可以接受任何實現了 Person 介面的對象,無論它實際上是 Person 還是 Impostor。這使得 greetBob 可以處理不同類型的對象,而不需要知道它們的具體類型:
String greetBob(Person person) => person.greet('Bob');
  1. 運行 main() 函式:
void main() {
print(greetBob(Person('Kathy'))); // Hello, Bob. I am Kathy.
print(greetBob(Impostor())); // Hi Bob. Do you know who I am?
}