Dart類


Dart是一種物件導向的語言。它支援物件導向的程式設計功能,如類,介面等。OOP方面的類是建立物件的藍圖/模板。類封裝了物件的資料。Dart為類概念提供了內建支援。

宣告一個類

使用class關鍵字在Dart中宣告一個類。類定義以關鍵字class開頭,後跟類名; 並且由一對花括號包圍的類體。下面給出了宣告語法 -

語法

class class_name {  
   <fields> 
   <getters/setters> 
   <constructors> 
   <functions> 
}

class關鍵字後跟類名。在命名類時必須考慮識別符號的規則。類定義可包括以下內容 -

  • 欄位(fields) - 欄位是類中宣告的任何變數,欄位表示與物件有關的資料。
  • setters和getters - 允許程式初始化和檢索類欄位的值,預設的getter/setter與每個類相關聯。但是可以通過顯式定義setter/getter來覆蓋預設值。
  • 建構函式(constructors) - 負責為類的物件分配記憶體。
  • 函式(functions) - 函式表示物件可以採取的操作,它們有時也稱為方法。

這些元件放在一起稱為類的資料成員。

範例:宣告一個類

class Car {  
   // field 
   String engine = "EA888";  

   // function 
   void disp() { 
      print(engine); 
   } 
}

該範例宣告了一個類Car。該類有一個engine的欄位。disp()是一個簡單的函式,用於列印欄位引擎的值。

建立類的範例

使用new關鍵字後跟類名來建立類的範例。下面給出了相同的語法 -

語法

var object_name = new class_name([ arguments ])
  • new關鍵字負責範例化。
  • 表示式的右側呼叫建構函式。如果引數化,建構函式應該傳遞值。

範例:範例化一個類

var obj = new Car("Engine 1")

存取屬性和函式

可以通過物件存取類的屬性和函式。使用.點表示法(稱為句點)來存取類的資料成員。

//accessing an attribute 
obj.field_name  

//accessing a function 
obj.function_name()

範例

參考以下範例以了解如何在Dart中存取屬性和函式 -

void main() { 
   Car c= new Car(); 
   c.disp(); 
}  
class Car {  
   // field 
   String engine = "EA888";  

   // function 
   void disp() { 
      print(engine); 
   } 
}

執行上面範例程式碼,得到以下結果 -

EA888

Dart建構函式

建構函式是類的特殊函式,負責初始化類的變數。Dart定義了一個與該類名稱相同的建構函式。建構函式是一個函式,因此可以引數化。但是與函式不同,建構函式不能具有返回型別。如果未宣告建構函式,則它會提供預設的無引數建構函式。

語法

class_name(parameter_list) { 
   //constructor body 
}

範例

以下範例顯示如何在Dart中使用建構函式 -

void main() { 
   Car c = new Car('EA888'); 
} 
class Car { 
   Car(String engine) { 
      print(engine); 
   } 
}

執行上面範例程式碼,得到以下結果 -

EA888

命名建構函式

Dart提供了命名建構函式,以使類定義多個建構函式。命名建構函式的語法如下所示 -

語法:定義建構函式

class_name.constructor_name(param_list)

範例

以下範例顯示如何在Dart中使用命名建構函式 -

void main() {           
   Car c1 = new Car.namedConst('EA888');                                       
   Car c2 = new Car(); 
}           
class Car {                   
   Car() {                           
      print("Non-parameterized constructor invoked");
   }                                   
   Car.namedConst(String engine) { 
      print("The engine is : ${engine}");    
   }                               
}

執行上面範例程式碼,得到以下結果 -

The engine is : EA888 
Non-parameterized constructor invoked

this關鍵字

this關鍵字參照類的當前範例。這裡,引數名稱和類欄位的名稱是相同的。因此,為了避免歧義,類的欄位以this關鍵字為字首。以下範例解釋相同 -

範例
以下範例說明在Dart中如何使用this關鍵字 -

void main() { 
   Car c1 = new Car('EA888'); 
}  
class Car { 
   String engine; 
   Car(String engine) { 
      this.engine = engine; 
      print("The engine is : ${engine}"); 
   } 
}

執行上面範例程式碼,得到以下結果 -

The engine is : EA888

Dart類Getters和Setter

Getters和Setter(也稱為存取器和更改器)允許程式分別初始化和檢索類欄位的值。使用get關鍵字定義getter或存取器。Setter或存取器是使用set關鍵字定義的。

預設的getter/setter與每個類相關聯。但是,可以通過顯式定義setter/getter來覆蓋預設值。getter沒有引數並返回一個值,setter只有一個引數但不返回值。

語法:定義一個getter

return_type  get identifier 
{ 
}

語法:定義一個setter

set identifier 
{ 
}

範例

以下範例顯示在Dart類中如何使用getter和setter -

class Student { 
   String name; 
   int age; 

   String get stud_name { 
      return name; 
   } 

   void set stud_name(String name) { 
      this.name = name; 
   } 

   void set stud_age(int age) { 
      if(age<= 15) { 
        print("Age should be greater than 15"); 
      }  else { 
         this.age = age; 
      } 
   } 

   int get stud_age { 
      return age;     
   } 
}  
void main() { 
   Student s1 = new Student(); 
   s1.stud_name = 'Maxsu'; 
   s1.stud_age = 0; 
   print(s1.stud_name); 
   print(s1.stud_age); 
}

該程式程式碼應產生以下輸出 -

Age should be greater than 15 
Maxsu 
Null

類繼承

Dart支援繼承的概念,它是程式從現有類建立新類的能力。擴充套件為建立較新類的類稱為父類別/超類。新建立的類稱為子/子類。

一個類使用extends關鍵字從另一個類繼承。子類繼承除父類別的建構函式之外的所有屬性和方法。

語法

class child_class_name extends parent_class_name

註 - Dart不支援多重繼承。

範例:類繼承

在下面的範例中宣告了一個類Shape,這個類從Circle類擴充套件。由於類之間存在繼承關係,因此子類(即Circle類)獲得對其父類別資料成員的隱式存取。

void main() { 
   var obj = new Circle(); 
   obj.cal_area(); 
}  
class Shape { 
   void cal_area() { 
      print("calling calc area defined in the Shape class"); 
   } 
}  
class Circle extends Shape {}

執行上面範例程式碼,得到以下結果 -

calling calc area defined in the Shape class

繼承的型別

繼承可以是以下三種型別 -

  • 單層 - 每個類最多可以從一個父類別擴充套件。
  • 多層 - 一個類可以從多個類繼承,Dart不支援多重繼承。
  • 多級 - 類可以從另一個子類繼承。

範例

以下範例顯示了多級繼承的工作原理 -

void main() { 
   var obj = new Leaf(); 
   obj.str = "hello"; 
   print(obj.str); 
}  
class Root { 
   String str; 
}  
class Child extends Root {}  
class Leaf extends Child {}  
//indirectly inherits from Root by virtue of inheritance

Leaf類通過多級繼承從Root類和Child類派生屬性。輸出如下 -

hello

Dart類繼承和方法重寫

方法重寫是子類在其父類別中重新定義方法的機制。以下範例說明了相同的情況 -

範例

void main() { 
   Child c = new Child(); 
   c.m1(12); 
} 
class Parent { 
   void m1(int a){ print("value of a ${a}");} 
}  
class Child extends Parent { 
   @override 
   void m1(int b) { 
      print("value of b ${b}"); 
   } 
}

執行上面範例程式碼,得到以下結果 -

value of b 12

重寫方法時,函式引數的數量和型別必須匹配。如果引數數量或其資料型別不匹配,Dart編譯器將丟擲錯誤。如下所示 -

import 'dart:io'; 
void main() { 
   Child c = new Child(); 
   c.m1(12); 
} 
class Parent { 
   void m1(int a){ print("value of a ${a}");} 
} 
class Child extends Parent { 
   @override 
   void m1(String b) { 
      print("value of b ${b}");
   } 
}

執行上面範例程式碼,得到以下結果 -

value of b 12

static關鍵字

static關鍵字可以應用於類的資料成員,即欄位和方法。靜態變數保留其值,直到程式完成執行。靜態成員由類名參照。

範例

class StaticMem { 
   static int num;  
   static disp() { 
      print("The value of num is ${StaticMem.num}")  ; 
   } 
}  
void main() { 
   StaticMem.num = 12;  
   // initialize the static variable } 
   StaticMem.disp();   
   // invoke the static method 
}

執行上面範例程式碼,得到以下結果 -

The value of num is 12

super關鍵字

super關鍵字用於參照類的直接父級。supper關鍵字可用於參照超類的變數,屬性或方法等等。

範例

void main() { 
   Child c = new Child(); 
   c.m1(12); 
} 
class Parent { 
   String msg = "message variable from the parent class"; 
   void m1(int a){ print("value of a ${a}");} 
} 
class Child extends Parent { 
   @override 
   void m1(int b) { 
      print("value of b ${b}"); 
      super.m1(13); 
      print("${super.msg}")   ; 
   } 
}

執行上面範例程式碼,得到以下結果 -

value of b 12 
value of a 13 
message variable from the parent class