C 學習筆記(二) 封裝 繼承 多型

2021-10-10 02:42:46 字數 4230 閱讀 5205

2. 繼承

2.4 繼承和訪問修飾符

2.5 黎克特制替換原則

3. 多型

封裝、繼承、多型是物件導向的三大特點,而在c#也是不例外,這篇文章將闡述封裝、繼承、多型的用法和思想。

封裝,就是將類的屬性和方法封閉起來,外部成員不可直接呼叫,只能通過預留的介面訪問。

封裝允許類自身的屬性和方法被一些可信物件操作,如繼承自該類的物件,而一些不可信的類則不允許其修改。在一定程度上保證了類內資料的穩定性。

同時,封裝也能夠簡化程式設計——有時候我們並不想知道其原理,只需要會呼叫即可。外部的物件只需要訪問乙個簡單的介面函式,就可以完成一件任務,很輕鬆的一件事。

訪問修飾符 class 類名

類的訪問修飾符可以定義為private、protected、public,通過訪問修飾符,類的屬性或方法可以選擇是否允許被外部訪問,從而限制了外部的許可權,保護了內部的資料的穩定性。

訪問修飾符 class 類名

set }…

類的成員;

}

屬性是物件的性質與物件之間關係的統稱。和字段一樣,屬性是類的成員,有訪問修飾符,有型別。

通常,定義欄位為私有,然後再定義乙個與該字段對應的屬性,具有對外的set和get方法。如下圖:

public

class

guyget

}}

guy是乙個類,name是其欄位,而name是與其對應的屬性,name能夠被外部訪問,就好像對應name為public一樣,直接訪問。

get和set是屬性訪問器,get和set訪問器有預定義的語法格式,可以把屬性訪問器理解為方法。

set訪問器用於設定資料,value是呼叫屬性是賦給屬性的值;get訪問器用於返回資料,必須有return語句,其返回值與屬性類別是一致的。

在set和get方法裡,可以做相應的判斷和操作,可以將set和get看做乙個方法,在裡面做需要的操作。

當然,屬性也可以簡化:

public

class

guy}

繼承就是在已存在的類基礎上,建立乙個新類,保留原有類的屬性和方法,同時又可以增加新的內容。

已存在的類稱為基類或父類,新建的類稱為派生類或父類。

//基類

public

class

animal

public

animal

(string name)

//建構函式

}//派生類

public

class

dog:

animal

}

上面的**實現了dog類繼承自animal類,子類自動繼承了基類的屬性name。

呼叫base(引數列表)實現呼叫基類的帶引數的建構函式。即使不使用base(),編譯器也會先呼叫基類的不帶參建構函式,再執行子類的建構函式。

和c++不同,在c#中乙個子類只能有乙個父類,而c++是可以繼承多個父類的。繼承的單一性也使得c#的基礎關係比較簡單,易於管理維護。

object類是所有類的基類。clr執行時,要求所有的型別,不管是系統定義的類還是使用者自定義的類,都必須從object派生。

//1.隱式派生

class

guy//2.顯式派生

class

guy:

system.object

//兩者實際上是一樣。

當乙個子類被乙個新類繼承時,新的類不僅繼承子類的屬性和方法,子類的父類的內容也將繼承下來。

c#繼承的單根性與傳遞性的繼承關係,形成了樹狀層次結構,基類和它的派生類存在一種層次關係。

之前,關於類的定義時有講到訪問修飾符。在c#中,有4中不同的訪問修飾符:

(1)pirvate:只能在本類中被訪問,只可以被本類所訪問,不能被繼承。

(2)public:可以在專案外被訪問,任意訪問,可以被繼承。

(3)protected:只能在本類中被訪問,可以被繼承。

(4)internal:只能在同一程式集中被訪問,可以跨類。可以被繼承。

在c#中,新增了internal這一關鍵字。internal的作用域為同一程式集。程式集的概念可以理解為乙個工程、專案,編譯後的dll檔案或exe檔案。也就是說,internal修飾符修飾後,該類只能在單一工程內訪問,如果其他專案訪問是不行的。

這位博主關於internal的總結不錯

如果沒有顯式地定義訪問修飾符,則c#的預設訪問許可權如下。

(1)在namespace中的類、介面預設為internal。如果不是巢狀的類,命名空間或編譯單元內的類只可以顯式地定義為public、internal型別,不允許是其他訪問型別。

(2)在類中,所有的成員均預設為private。可以顯式地定義為public、private、protected、internal或protected internal訪問型別。

任何基類可以出現的地方,派生類一定可以出現。也就是說,可以用派生類物件代替基類物件,可以讓乙個基類的引用指向乙個派生類的物件。

//基類

public

class

animal

public

animal

(string name)

//建構函式

}//派生類

public

class

dog:

animal

}//栗子

dog dog =

newdog()

;//例項化物件

animal animal =

newdog()

;//使用黎克特制替換原則,基類物件指向派生類

在物件導向程式設計中,多型(polymorphism)是類的三大特性之一,從一定角度來看,封裝和繼承幾乎都是為多型而準備的。

封裝、繼承、多型這三大特性是相互關聯的,封裝是基礎,繼承是關鍵,多型性是補充。

多型性存在於繼承性之中,它是繼承性的進一步擴充套件。沒有繼承就沒有多型。通過多型可以實現**重用,減少**量,提高**的可擴充套件性和可維護性。

多型性分為編譯時的多型性和執行時的多型性

編譯時的多型性是通過過載來實現的。對於非虛的成員來說,系統在編譯時,根據傳遞的引數、返回的型別等資訊決定實現何種操作。具有執行速度快的特點。

//基類

public

class

animal

}//派生類

public

class

dog:

animal

}

過載是通過new修飾符來實現的,這樣dog類呼叫hello()時將覆蓋掉animal類的hello函式,呼叫自身的hello()函式。

執行時的多型性是指直到系統執行時,才根據實際情況決定實現何種操作。c#中執行時的多型性是通過重寫實現。具有高度靈活和抽象的特點。

//基類

public

class

animal

}//派生類

public

class

dog:

animal

}

重寫,需要將父類的hello()加上修飾符virtual,而子類的hello()加上修飾符override,表示重寫基類的虛方法。

如果使用黎克特制替換原則,即使用基類物件指向子類物件,那麼會出現問題:究竟是呼叫哪個函式呢?

(1)使用new過載,那麼還是呼叫基類的方法。

(2)使用virtual和overide重寫,那麼將呼叫子類自己的方法。

也就是說,基於重寫可以實現多型,而過載方法不行。

C 學習筆記(5) 封裝 繼承 多型

封裝 每個物件都能包含它能進行操作所需要的所有資訊,這個特性稱為封裝,因此物件不必依賴其他物件來完成自己的操作。封裝的好處 l 良好的封裝能夠減少耦合。l 類內部的實現可以自由地修改。l 類具有清晰的對外介面。繼承 物件的繼承代表了一種 is a 的關係,如果兩個物件a和b,可以描述為 b是a 則表...

203 07 05 封裝 繼承 多型

繼承 1 oc是單一繼承 2 封裝 隱藏內部 m檔案 實現 穩定外部 h檔案 介面。屬性封裝了例項變數 方法封裝了具體實現 類封裝了方法和屬性 封裝的好處 使用更加簡單,變數更加安全,可以隱藏內部實現細節,開發速度快 3 私有變數 private,私有方法 在.m中實現,在.h中沒有宣告,私有成員變...

python 20200317封裝 繼承 多型

展開python 中的 self 相當於c 中的this指標。init self init方法 構建方法,當你在初始化乙個物件時 這個方法就會在物件被建立時 自動呼叫 class ball def init self,name attention self.name name def kick se...