天天看點

Dart語言學習日記(七)類

Dart語言面向對象程式設計

    • 面像對象的基本特征
      • 1.抽象
      • 2.封裝
      • 3.繼承
      • 4.多态
    • 類的定義和使用
      • 1.類的定義
    • 構造方法
      • 1.預設構造方法
      • 2.類名構造方法
      • 3.命名構造方法
    • 存儲器和通路器
    • 類的繼承
      • 繼承的定義
      • 父類方法的覆寫
      • 繼承中的多态
      • 構造方法的調用

面像對象的基本特征

1.抽象

在面向對象的程式設計方法中,各種事物稱為“對象”,将同一事物的共同特征概括出來的過程稱為抽象,抽象包括資料抽象和過程抽象。

資料抽象:例如,人有國籍、膚色、姓名、性别、年齡等共同特征。

過程抽象:例如,人會吃飯、走路、講話、思考等共同行為。

2.封裝

封裝就是在對某一類事物完成抽象後,通過某種文法形式,将資料(屬性)與操作資料(行為)的源代碼進行有機的結合,形成“類”。

封裝可以将對象一部分屬性和方法隐藏起來。

class Person{
	String name;//屬性
	String nation;
	void say(){};//行為,又稱為方法
	void eat(){};
}
           

3.繼承

繼承指的是兩種或者兩種以上的類之間的聯系與差別,是後者延續前者的某些方面的特點,對象的一個新類可以從現有的原始類中派生,這個過程稱為繼承,新類稱為子類或派生類,原始類稱為新類的父類或基類。

例如,中國人是人的子類、英國人也是人的子類,不管中國人還是英國人都有國籍、膚色、姓名、性别、年齡等屬性,也都會吃飯、說話、走路和思考等行為,但他們的吃飯方式、講話語言都是不一樣的。

class Chinese extends Person{
}
class British extends Person{
}
           

4.多态

多态是指當不同的多個對象同時收到同一個完全相同的消息之後,所表現出來的動作是各不相同的,具有多種形态。

例如,中國人、英國人都有吃飯的方法,但中國人用筷子吃飯、英國人用刀叉吃飯。

多态通常用覆寫或重載的方式實作。覆寫是指在子類中重新定義父類某種特寫的方法。重載是指允許類中存在多個同名的方法,而這些方法的參數表不同(參數個數不同、參數類型不同或兩者都不同)。

class Chinese extends Person{
	@override		//覆寫,重寫
	void eat(){
		print('筷子');
	}
}
class British extends Person{
	@override		//覆寫,重寫
	void eat(){
		print('刀叉');
	}
}
           

類的定義和使用

1.類的定義

class 類名 {
	屬性的定義;
	...
	方法的定義;
	...
}
           

在定義類時,如果沒有給成員變量提供初始值,則建立對象時成員變量的初始值預設為null;如果指定了成員變量的類内初始值,則建立對象時類内初始值将用于初始該成員變量。

定義一個Person類,包含姓名、性别、年齡、國籍4個屬性和1個說話方法:

class Person{
	String name;		//姓名
	String sex;			//性别
	int age;			//年齡
	String nation;		//國籍
	void say(){
		print('會說$(this.nation)語言');
	}
}
           

構造方法

類的構造方法(構造函數)是類的一種特殊的成員方法,它會在每次建立類的新對象時執行。

構造方法不會傳回任何類型,也不會傳回void;

構造方法可用于為某些成員變量設定初始值。

Dart語言中的構造方法包括預設構造方法、類名構造方法和命名構造方法三種。

1.預設構造方法

在類中如果沒有顯式定義構造方法,系統會預設定義一個空的構造方法,該構造方法設有參數,它的名稱預設與類名一樣。

class Person{
	Person(){};//顯示定義,預設構造方法
	String name;
	int age;
	void say(){
		print('say');
}
           

2.類名構造方法

類名構造方法就是類中定義的方法名與類名完全一樣,類名構造方法的定義格式如下:

class 類名 {
	屬性的定義;
	...
	類名(參數類型){
		//構造方法體
	}
	方法的定義;
	...
}
           

定義一個Person類,包含姓名、性别、年齡、國籍4個屬性、1個構造方法和1個說話方法:

Person( name, sex, age, nation){//類名構造方法
	this.name = name;
	this.sex = sex;
	this.age = age;
	this.nation = nation;
}
           

3.命名構造方法

命名構造方法就是類中定義的方法名與類名不完全一樣的方法。命名構造方法的定義格式如下:

class 類名 {
	屬性的定義;
	...
	類名.辨別(參數清單){
		//構造方法體
	}
	方法的定義;
	...
}
           

用命名構造方法實作Person類的定義和執行個體化:

Person.create( name, sex, age, nation){//命名構造方法
	this.name = name;
	this.sex = sex;
	this.age = age;
	this.nation = nation;
}

/*執行個體化類對象*/
Person japanese = Person.create('岡本松田','男',21,'日本');
           

存儲器和通路器

Dart語言中可以使用set關鍵字定義存儲器(setter),使用get關鍵字定義通路器(getter)。

定義存儲器如下:

set 屬性名(參數){
	//功能代碼
}
           

定義通路器如下:

傳回值類型 get 屬性名{
	return 表達式;//傳回屬性值
}
           

定義一個求矩形面積的類,實作通路器取出面積值、存儲器設定矩形的高和寬:

class Rect{
	double width;
	double height;
	Rect(this.width,this.height);
	set newHeight(value){
		this.height = value;
	}
	set newWidth(value){
		this.width = value;
	}
	double get area {
		return this.width*this.height;
	}
}

/*調用*/
Rect rect = Rect(1.2,4.5);
print(rect.area);
rect.newHeight = 12.0;
print(rect.area);
           

類的繼承

繼承的定義

使用extends關鍵字繼承一個類,子類會繼承父類可見的屬性和方法,不會繼承構造方法,定義形式如下:

class 子類名 extends 父類名 {
	子類屬性
	子類方法
}
           

定義一個Shape類,包含1個name屬性和1個show()方法;定義一個繼承子Shape類的子類Circle,包含1個r屬性和1個area()方法。

class Shape{
	String name;		//形狀的名稱
	void show(){
		print(thsi.name);//輸出形狀名稱
	}
}
class Circle extends Shape{
	double r;		//圓的半徑
	double area(){	//計算圓的面積
		return 3.14*r*r;
	}
}
           

Dart不支援多重繼承,每個類最多可以從一個父類繼承,類可以從另一個子類繼承。

父類方法的覆寫

"@override"代碼讓子類能夠覆寫父類的方法、通路器(getter)和存儲器(getter)。

在Circle子類中覆寫Shape類的show()方法:

class Circle extends Shape{
	double r;		//圓的半徑
	double area(){	//計算圓的面積
		return 3.14*r*r;
	}
	@override
	void show(){
		print(this.name + '半徑:' + this.r.toString());
	}
}
           

覆寫方法時,方法的參數數量和類型必須比對,也可以在Circle子類覆寫show()方法中調用父類的方法。

super.show();
           

繼承中的多态

Dart語言中的多态就是父類定義一個完全沒有實作或部分實作的方法,讓繼承它的子類去實作,這樣就可以讓每個子類有不同的表現行為。

class Rect{
	double width;
	double height;
	double area() {
		return width*height;
	}
	@override
	void show(){
		print(this.name + '寬:$width,高:$height,面積:' + this.area().toString() );
	}
}
           

構造方法的調用

1.如果父類中有無參構造方法,則子類的構造方法會預設調用父類的無參構造方法

定義一個Father類,該類包含1個無參構造方法;定義一個Child類,該類中包含1個無參構造方法:

void main(){
	Child child = Child();
}
class Father{
	Father(){
		print('Father......');
	}
}
class Child extends Father{
	Child(){
		print('Child......');
	}
}
           

2.如果父類沒有無參構造方法,則需要在構造方法參數後使用":"顯式調用父類的自定義構造方法。

定義一個Father類,該類中包含1個帶參數的構造方法;定義一個Child類,該類中包含1個帶參數的構造方法。

void main(){
	Child child = Child('kate');
}
class Father{
	String firstName;
	Father(this.firstName){
		print('Father\'s firstName: ......$firstName');
	}
}
class Child extends Father{
	Child(String firstName): super(firstName){
		print('Child\'s firstName: ......$firstName');
	}
}