上一篇,我們介紹了類別。類別裡面的成員有屬性以及函數。
Methods are functions that provide behavior for an object.
接下來,我們將以方法 (Method) 來稱呼類別裡面的函數。
關鍵字 this,表示該類別。在類別的方法內使用 this,可以使用定義於同類別但在方法外的屬性。
import 'dart:math';
class Point{
double x, y;
Point(this.x, this.y);
double distanceTo(double x, double y){
var dx = this.x - x;
var dy = this.y - y;
return sqrt(dx*dx + dy*dy);
}
}
我們也可以將自己存在的類別以引數方式傳入,
import 'dart:math';
class Point{
double x, y;
Point(this.x, this.y);
double distanceTo(Point other){
var dx = x - other.x;
var dy = y - other.y;
return sqrt(dx*dx + dy*dy);
}
}
針對類別的屬性,Dart 也提供了一組特別的方法來對屬性進行存取。
當實例化類別參考類別的屬性時,其實已經隱含了 getter/setter。
我們也可以利用關鍵字 get、set 設定屬性的 getter 、setter。
class Student{
String first_name;
String last_name;
int age;
Student(this.first_name, this.last_name, this.age);
String get full_name => '$first_name $last_name';
set full_name(String value){
final split_name = value.split(' ');
first_name = split_name[0];
last_name = split_name[1];
}
}
使用範例:
void main(){
var student = Student('Alex', 'Chen', 18);
print(student.fullname); // Alex Chen
student.fullname = 'Michael Jordan';
print(student.fullname); // Michael Jordan
print(student.firstname);// Michael
print(student.lastname); // Jordan
}
上面的範例中,我們在 setter 同時設定了其他屬性的值。因為這些屬性是有關聯的。
我們也可以改用方法完成。
class Student{
String first_name;
String last_name;
int age;
Student(this.first_name, this.last_name, this.age);
String get full_name => '$first_name $last_name';
void setFullName(String fullName){
first_name = fullName.split(' ')[0];
last_name = fullName.split(' ')[1];
}
}
當外部的呼叫者呼叫了 setFullName() 時,同樣也會修改 first_name, last_name。
void main(){
var student = Student('Alex', 'Chen', 18);
print(student.fullname); // Alex Chen
student.setFullName('Michael Jordan');
print(student.fullname); // Michael Jordan
print(student.firstname);// Michael
print(student.lastname); // Jordan
}
不過,Effective Dart 建議:
DO use setters for operations that conceptually change properties.
對於在概念上修改屬性的操作,使用 setters。
另外,如果屬性只有 setter 而沒有 getter。那麼,應該要將 setter 的運算改用方法完成。
class Student{
String first_name;
String last_name;
int age;
Student(this.first_name, this.last_name, this.age);
set full_name(String value){
final split_name = value.split(' ');
first_name = split_name[0];
last_name = split_name[1];
}
}
預設類別中的每一個屬性,函數都是可以被外部呼叫者看到的。如果某些屬性與函數僅在類別內部使用,那麼必須要將屬性或是方法名稱前方加上下底線。
class SampleClass{
String value1;
String value2;
String _privateValue1;
int _privateValue2;
void doSomething1(){
...
}
void doSomething2(){
...
}
void _privateDoSomething(){
...
}
}
如此一來,外部的呼叫者就無法呼叫函數或方法名稱開頭是為底線的物件。
每個類別都有專屬的功能,不同的類別裡面包含著不同的屬性以及方法。
利用上一篇介紹的建構式,我們將值帶入類別內的屬性,本篇文章介紹了如何使用方法以及屬性的 getter 、setter。
setter 的功能看似與方法相近,但是 setter 比較接近修改屬性的操作。但是,如果一個屬性只有setter 而沒有 getter,是可以用方法替換的。
最後,設計類別時,不一定要將每一個類別內的成員都公開給外部參考,在名稱前方加上下底線,就可以將屬性或是方法的可見性限制在類別內,換句話說,外部的呼叫者就看不到該物件。