前面說到 Dart 是一個支援OOP的程式語言(附註*),而不同於JS的Prototype-based,Dart 則是 Class-based,所以在OOP上會比較像是Java之類的語言。
在 Dart 中 class的宣告很簡單
class Person {
final String name;
final int age;
final String email;
late final String position; // 請先無視這個late 之後會提到null safety時會再說明
Person(this.position,
{required this.name, required this.age, required this.email});
Person.developer(
{required this.name, required this.age, required this.email}) {
this.position = 'developer';
}
void hello() {
print('hi 我是 $name 我的職業是 $position');
}
}
我們可以直接宣告一些變數來表示這個class的fields以及一些function來表示這個class的method,這些統稱是class members,那這個與class同名的function Person
是什麼呢?
這個就是所謂的建構子(constructor),在OOP中 class
可以想像成一個模板,而所謂的物件就是按照模板產生出來的東西,這個過程又稱為實體化(instantiation)
而在OOP裡負責這件事情就是 constructor ,而constructor當然可以不只有一個,我們可以宣告多個constructor來因應各種需求,像是可能許多人的 position
都是 developer那我們可以宣告一個 constructor 叫做 Person.developer
來減少我們只用原本的constructor還要一直多傳 position
的煩躁感。
真正在程式中run起來會像是這樣子:
void main() {
final todd = Person('developer',name:'todd',age:25,email:'123@gamil.com');
final larry = Person.developer(age:25,name:'larry',email:'456@gamil.com');
print(todd.email);
print(todd.name);
print(todd.job);
print(todd.age);
todd.hello();
larry.hello();
}
也許有人已經注意到為什麼在Person(this.position,{required this.name, required this.age, required this.email});
有些參數是放在 {}
裡有些參數是放在前面,他們差別在哪裡?直接放在前面的參數是required positional parameters 而放到大括號中的是 Named parameters。
從這個例子先不考慮有default value(optional parameters )的情況下我們就能看得出 positional parameters它就跟一般function一樣我們要必須傳值並且要依照參數順序,而Named parameters就是我們以key:value
的形式傳入參數而且 {}
裡的順序可以隨意但必須在positional parameters後傳入。
在 Dart class constructor 中有提供一個語法糖 factory
,我們先來看看它的大概會長怎麼樣,稍微將上面的 Person Class 修改一下後:
class Person {
final String name;
final int age;
final String email;
late final String position;
Person(
{required this.name,
required this.age,
required this.email,
required this.position});
Person.developer(
{required this.name, required this.age, required this.email}) {
this.position = 'developer';
}
factory Person.todd(String name) {
return Person(
name: name, age: 25, email: '123@gamil.com', position: 'developer');
}
void hello() {
print('hi 我是 $name 我的職業是 $position');
}
}
最直觀的差異就是 factory
constructor 會回傳一個 instance ,而不是像一般的 constructor 只要傳入值或者對this操作來設定值且不用另外撰寫return相關的語法。也因為是直接回傳 instance 所以就無法對 this
操作。
那實際上 factory
有什麼用途?
大致上有三種
在這裡我就先不詳細實作每種用法,如果有興趣可以查閱文章最後的參考資料。
下篇文章會繼續講解在Dart 中 class 的其他語法,預期會有 private、getter、setter 等等物件導向相關的語法及操作。
附註*:為什麼我不直接稱Dart為「物件導向程式語言」而是用「支援物件導向的程式語言」,主要是因為Dart不只支援一種 Programming paradigm,而我平常在工作中是比較常使用FP的概念在開發,所以面對這種支援多種 paradigm 的語言時我就不太喜歡稱為它是某個特定 paradigm 的語言。
參考資料:https://stackoverflow.com/questions/53886304/understanding-factory-constructor-code-example-dart