這些基礎卻重要的物件導向概念,你還記得多少

MiroYuan發表於2015-09-24

物件導向概念一覽:

物件,類,構造方法,方法過載,屬性,欄位。

物件導向三大特性:封裝,繼承,多型

抽象類,介面

集合,裝箱拆箱

這些概念你還記得多少?

有不清楚的就往下看吧,溫故而知新。

 

整理如下:

物件 是一個自包含的實體,用一組可識別的特性和行為來標識。

物件導向程式設計 Object-Oriented Programming

 

就是具有相同的屬性和功能的物件的抽象的集合。

 

構造方法,又叫建構函式,其實就是對類進行初始化。

構造方法與類同名,無返回值,也不需要void,在new的時候呼叫。

所有類都有構造方法,如果你不編碼則系統預設生成空的構造方法,若你有定義的構造方法,那麼預設的構造方法就會失效了。

 

方法過載 提供了建立同名的多個方法的能力,但這些方法需要使用不同的引數型別。

方法過載時,方法名相同,但引數型別或個數必須不同。

方法過載可在不改變原方法的的基礎上,新增功能。

 

屬性 是一個方法或一對方法,但在呼叫它的程式碼看來,它是一個欄位,即屬性適合於以欄位的方式使用方法呼叫的場合。

欄位 是儲存類要滿足其設計所需要的資料,欄位是與類相關的變數。

屬性有兩個方法 get 和 set . 

get訪問器返回與宣告的屬性相同的資料型別;

set訪問器沒有顯式設定引數,但它有一個隱式引數value, 它的作用是呼叫屬性時可以給內部的欄位或引用賦值。

變數私有的叫欄位,公有的是屬性,那麼對方法而言,同樣也就有私有方法和公有方法。

 

物件導向三大特性:封裝,繼承,多型

封裝

每個物件都包含它能進行操作所需要的所有資訊,這個特性稱為封裝,因此物件不必依賴其他物件來完成自己的操作。

封裝有很多好處:減少耦合;類內部的實現可以自由地修改;類具有清晰的對外介面。

 

繼承

物件的繼承代表了一種 is-a 的關係,如果兩個物件 A和B, 可以描述為 B是A , 則表明 B 可以繼承 A

實際上,繼承者還可以理解為是對被繼承者的特殊化,因為它除了具備被繼承者的特性外,還具備自己獨有的個性。

繼承定義了類如何相互關聯,共享特性。

繼承的工作方式是定義父類和子類,或叫做基類和派生類,其中子類繼承父類的所有特性。子類不但繼承了父類的所有特性,還可以定義新的特性。

學習繼承記住三句話:

1.子類擁有父類非private的屬性和功能;

2.子類具有自己的屬性和功能,即子類可以擴充套件父類沒有的屬性和功能;

3.子類還可以以自己的方式實現父類的功能(方法重寫)。

在C#中子類從它的父類中繼承的成員有 方法、域、屬性、事件、索引指示器。

但對於構造方法,有一些特殊,它不能被繼承,只能被呼叫。

對於呼叫父類的成員,可以用base關鍵字。例如:

public Cat(string name) : base(name)

{}

如上例子,子類構造方法需要呼叫父類同樣引數型別的構造方法,用base關鍵字代表父類

繼承是有缺點的,父類變,則子類不得不變;另外,繼承會破壞封裝,父類實現細節暴露給子類,增大了兩個類之間的耦合性。

繼承顯然是一種類與類之間強耦合的關係。

不要濫用,當類具備 is-a 的關係, 考慮用繼承。

 

多型

多型表示不同的物件可以執行相同的動作,但要通過它們自己的程式碼來執行。

1.子類以父類身份出現

2.子類在工作時以自己的方式來實現

3.子類以父類的身份出現時,子類特有的屬性和方法不可以使用

 

如何使用:虛方法和方法重寫。

通常虛擬的是方法,但其實除了欄位不能是虛擬的,屬性、事件和索引器都可以是虛擬的。

子類可以選擇使用override關鍵字,將父類實現替換為自己的實現,這就是方法重寫Override,或者叫做方法覆寫。

注意:物件的宣告必須是父類,而不是子類,例項化的物件是子類,這才能實現多型。

多型的原理是當方法被呼叫時,無論物件是否被轉換為其父類,都只有位於物件繼承鏈最末端的方法實現會被呼叫。

也就是說,虛方法是按照其執行時型別而非編譯時型別進行動態繫結呼叫的。

 

抽象類

考慮把例項化沒有任何意義的父類,改成抽象類。

C#允許把類和方法宣告為 abstract, 即抽象類和抽象方法。

注意:

1.抽象類不能例項化

2.抽象方法是必須被子類重寫的方法

3.如果類中包含抽象方法,那麼類就必須被定義為抽象類,不論是否還包含其他一般方法

 

讓抽象類擁有儘可能多的共同程式碼,擁有儘可能少的資料。

抽象類通常代表一個抽象概念,它提供一個繼承的出發點,當設計一個新的抽象類時,一定是用來繼承的。

所以,在一個以繼承關係形成的等級結構裡面,樹葉節點應當是具體類,而樹枝節點均應當是抽象類。

 

介面

介面是把隱式公共方法和屬性組合起來,以封裝特定功能的一個集合。

一旦類實現了介面,類就可以支援介面所支援的所有屬性和成員。

宣告介面在語法上與宣告抽象類完全相同,但不允許提供介面中任何成員的執行方式。

所以介面不能例項化,不能有構造方法和欄位;不能宣告虛擬的或靜態的等。

實現類就必須要實現介面中的所有方法和屬性。

介面中的方法或屬性前面不能有修飾符、方法沒有方法體。例子:

public interface IBankAccount

{

void PayIn(decimal amount);

bool Withdraw(decimal amount);

decimal Balance

{

get;

}

}

抽象類和介面的區別:

從表象上來說,抽象類可以給出一些成員的實現,介面卻不包含成員的實現;

抽象類的抽象成員可被子類 部分實現,介面的成員需要實現類 完全實現;

一個類只能繼承一個抽象類,但可實現多個介面等等。

三點幫助區分抽象類和介面:

1. 類是對物件的抽象;抽象類是對類的抽象;介面是對行為的抽象

2. 如果行為跨越不同類的物件,可使用介面;對於一些相似的類物件,用繼承抽象類

3. 從設計角度講,抽象類是從子類中發現了公共的東西,泛化出父類,然後子類繼承父類;

    而介面是根本不知子類的存在,方法如何實現還不確認,預先定義。

 

抽象類是自底向上抽象出來的,而介面是自頂向下設計出來的。

 

集合

陣列優點, 比如說陣列在記憶體中連續儲存,因此可以快速而容易地從頭到尾遍歷元素,可以快速修改元素等等。

陣列缺點,建立時必須要指定陣列變數的大小,還有兩個元素之間新增元素也比較困難。

.NET Framework 提供了用於資料儲存和檢索的專用類,這些類統稱集合

這些類提供對堆疊、佇列、列表和雜湊表的支援。大多數集合實現相同的介面。

介紹常用的一種:ArrayList

ArrayList 是名稱空間 System.Collections 下的一部分, 它是使用大小可按需動態增加的陣列實現IList介面。

ArrayList 的容量是 ArrayList 可以儲存的元素數。 ArrayList 的預設初始容量為0。

隨著元素新增到 ArrayList中,容量會根據需要通過重新分配自動增加。

使用整數索引可以訪問此集合中的元素。此集合中的索引從零開始。

例子:

IList arrayAnimal;

arrayAnimal = new ArrayList();

arrayAnimal.Add(new Cat("小花"));

。。。

 

ArrayList不是型別安全的。需要使用裝箱拆箱操作,帶來效能損耗。

裝箱:把值型別打包到Object引用型別的一個例項中。

int i = 123;

object o=(object)i; // boxing

拆箱:從物件中提取值型別。

i=(int)o; // unboxing

 

泛型是具有佔位符(型別引數)的類、結構、介面和方法。

使用泛型解決型別不安全及裝拆箱效能損耗問題。

泛型集合使用 System.Collections.Generic 的名稱空間

List 類就是 ArrayList 類的泛型等效類。

該類使用大小可按需動態增加的陣列實現 IList 泛型介面。

IList<Animal> arrayAnimal;

arrayAnimal = new List<Animal>();

arrayAnimal.Add( new Cat("小花"));

 

說明:

常常用List代替ArrayList, 其實 List 和 ArrayList 在功能上是一樣的。

不同就在於, 它在宣告和例項化時都需要指定其內部項的資料或物件型別,這就避免了型別安全問題和裝箱拆箱的效能問題。

通常情況下,都建議使用泛型集合。

 

相關文章