物件導向之封裝與多型

2021-08-27 07:08:29 字數 3795 閱讀 6022

封裝的實質是資訊的隱藏,通過封裝對外界隱藏了物件的屬性和實現細節,僅對外公開介面,控制在程式中屬性的讀和修改的訪問級別。

字面上講,封裝就是把某個事物包起來,使外界不知道該事物的具體內容。在物件導向的程式中,把資料和實現操作的**集中起來,放在物件內部。於是它們就被放在黑盒子裡面,從外觀是看不見的,更不能從外面直接訪問或修改這些資料和**。

封裝的目的是增強安全性和簡化程式設計,使用者不必了解具體的實現細節,而只是要通過外部介面,以特定的訪問許可權來使用類的成員。

封裝應遵循如下原則:

(1).有乙個清晰的邊界,所有私有資料和實現操作的**都被封裝在這個邊界內,從外面看不到,更不能直接訪問。

(2).有確定的介面(即協議),這些介面就是物件可以接收的訊息,只能通過向物件傳送訊息來使用它。

(3).受保護的內部實現,實現物件功能的細節(私有資料和**)不能在定義該物件的類的範圍外進行訪問。

多型是指子類物件可以像父類物件那樣被使用,同樣的訊息可以共享(公用)乙個行為(方法)的名字,然而不同層次中的每個類卻各自按自己的需要來實現這個行為。當物件接收到發給它的訊息時,根據該物件所屬於的類動態選用該類中定義的實現演算法。

**public

classanimal

}public

classcat:animal//(「:」在c#

中表示繼承

)

}public

classdog:animal

}classtester}}

輸出如下:

animal eat...

cat eat...

dog eat...

在上面的例子中,通過繼承,使得

animal

物件陣列中的不同的物件,在呼叫

eat()

方法時,表現出了不同的行為。

多型的實現看起來很簡單,要完全理解及靈活的運用

c#的多型機制,也不是一件容易的事,有很多需要注意的地方。

先看下面的例子。

2

**public

classanimal

}public

classcat:animal

}classtester}

執行結果為:

animal eat...

animal eat...

cat eat...

可以看出,當派生類

cat的

eat()

方法使用

new修飾時,

cat的物件轉換為

animal

物件後,呼叫的是

animal

類中的eat()

方法。其實可以理解為,使用

new關鍵字後,使得

cat中的

eat()

方法和animal

中的eat()

方法成為毫不相關的兩個方法,只是它們的名字碰巧相同而已。所以,

animal

類中的eat()

方法不管用還是不用

virtual

修飾,也不管訪問許可權如何,或者是沒有,都不會對

cat的

eat()

方法產生什麼影響(只是因為使用了

new關鍵字,如果

cat類沒用從

animal

類繼承eat()

方法,編譯器會輸出警告)。

我想這是設計者有意這麼設計的,因為有時候我們就是要達到這種效果。嚴格的說,不能說通過使用

new來實現多型,只能說在某些特定的時候碰巧實現了多型的效果。

真正的多型使用

override

來實現的。回過去看前面的例

1,在基類

animal

中將方法

eat()

用virtual

標記為虛擬方法,再在派生類

cat和

dog中用

override

對eat()

修飾,進行重寫,很簡單就實現了多型。需要注意的是,要對乙個類中乙個方法用

override

修飾,該類必須從父類中繼承了乙個對應的用

virtual

修飾的虛擬方法,否則編譯器將報錯。

多層繼承中又是怎樣實現多型的。比如類

a是基類,有乙個虛擬方法

method()

(virtual

修飾),類

b繼承自類

a,並對

method()

進行重寫(

override

修飾),現在類

c又繼承自類

b,是不是可以繼續對

method()

進行重寫,並實現多型呢?看下面的例子。

3:**

public

classanimal

}public

classdog:animal

}public

classwolfdog:dog

}classtester}}

執行結果為:

animal eat...

dog eat...

wolfdog eat...

在上面的例子中類

dog繼承自類

animal

,對方法

eat()

進行了重寫,類

wolfdog

又繼承自

dog,再一次對

eat()

方法進行了重寫,並很好地實現了多型。不管繼承了多少層,都可以在子類中對父類中已經重寫的方法繼續進行重寫,即如果父類方法用

override

修飾,如果子類繼承了該方法,也可以用

override

修飾,多層繼承中的多型就是這樣實現的。要想終止這種重寫,只需重寫方法時用

sealed

關鍵字進行修飾即可。

先在我們在來討論一下用

abstract

修飾的抽象方法。抽象方法只是對方法進行了定義,而沒有實現,如果乙個類包含了抽象方法,那麼該類也必須用

abstract

宣告為抽象類,乙個抽象類是不能被例項化的。對於類中的抽象方法,可以再其派生類中用

override

進行重寫,如果不重寫,其派生類也要被宣告為抽象類。看下面的例子。

例4:

**

public

abstract

classanimal

public

classcat:animal

}public

classdog:animal

}public

classwolfdog:dog

}classtester

{static

voidmain(stringargs)

{animalanimals=newanimal[3];

animals[0]=newcat();

animals[1]=newdog();

animals[2]=newwolfdog();

for(inti=0;i

執行結果為:

cat eat...

dog eat...

wolfdog eat...

從上面可以看出,通過使用

abstract-override

可以和virtual-override

一樣地實現多型,包括多層繼承也是一樣的。不同之處在於,包含虛擬方法的類可以被例項化,而包含抽象方法的類不能被例項化。

python物件導向 封裝and多型

為什麼講封裝之前要將這個東西?我才不會說為什麼 首先 python沒有介面類這個概念 哈哈哈.神經病 python抽象類和介面類更接近於一種規範,例如,我吃蘋果,吃香蕉,吃梨,這些我都可以統一歸到吃水果這個類中,但是我能吃到這個水果嗎?水果這個籠統的東西我能吃到嗎,我只能吃到具體的香蕉什麼的.這個規...

物件導向 封裝 繼承 多型

物件導向 封裝 繼承 多型物件導向 封裝 一 封裝 private 資料型別 名字 成員變數 public 預設一致 名字 屬性 set 類中不僅可以有成員變數和屬性,還可以有成員方法 訪問修飾符 4個 public 公共的,任何地方都可以訪問,但是需要引用 命名空間 private 私有的,類的內...

python物件導向之封裝 繼承和多型

類似於模板,把事物共有的特徵和行為進行打包,然後建立出來的物件就會具有這些特徵和行為。1.封裝資料的主要原因是 保護隱私 和 隔離複雜度 2.類的結構 class 類名 object 類名的命名規則 大駝峰命名法 每個單詞首字母大寫,單詞之間沒有下劃線 類屬性 屬性名 值 類方法 classmeth...