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