您現在的位置是:首頁 > 足球

Java中的封裝、繼承和多型,你真的都懂了嗎

  • 由 馬小凡學java 發表于 足球
  • 2021-12-23
簡介上面呢介紹了繼承普通類的知識,現在我們來看看不太正常的類,抽象類,抽象類是指被abstract修飾,包含抽象方法的類,如下就是一個抽象類,首先是類名前面添加了abstract關鍵字,其次是其中包含了一個抽象方法,什麼是抽象方法,就是沒有被具

ork方法是什麼意思

Java中的封裝、繼承和多型知識點是學習java必備的基礎知識,看似簡單,真正理解起來還是有一定難度的,今天小編再次透過例項程式碼給大家講解java 封裝繼承多型知識,感興趣的朋友一起學習下吧。

封裝

所謂的封裝就是把類的屬性和方法使用private修飾,不允許類的呼叫者直接訪問,我們定義如下一個類,可以看到所有的成員變數和成員方法都使用private修飾了,我們現在來使用一下這個類。

Java中的封裝、繼承和多型,你真的都懂了嗎

開啟百度APP看高畫質圖片

當我們使用的時候編譯器給出了下面這樣的報錯。

Java中的封裝、繼承和多型,你真的都懂了嗎

告訴我們說是private訪問控制,那麼這是什麼意思呢?我們來看看另外一張圖,那麼這張圖代表著什麼呢?在看這張圖之前,我們先來看看四者都提到的包,那麼包又是什麼呢,包可以簡單理解為一個資料夾,把類放到放到包裡面,也就相當於是專門的資料夾裡面,這不是我們說的重點,知道就行,類都知道吧,不知道的先去看看博主這篇部落格類和物件再回來繼續往下。

ps:稍微記一下這張圖中的內容。

Java中的封裝、繼承和多型,你真的都懂了嗎

Java中的封裝、繼承和多型,你真的都懂了嗎

有了上面的基礎我們現在再來看private,他的使用範圍只有

同一個包中的同一個類中使用(這個範圍也就是他的許可權)

,我們就記住

只能在我們定義的那個類中使用

就好了,別問為什麼,因為這就是語法,記住就好了,

記準確了是當前類中,不能外部引用

,否則就會出現上面那樣的報錯。既然不能直接從外部引用,那麼類的呼叫者總得有個辦法使用吧,不然實現這個類幹嘛,這個時候就是我們在設計類的時候要提供的公開的方法了,那麼上述的程式碼應該寫成如下形式。

Java中的封裝、繼承和多型,你真的都懂了嗎

Java中的封裝、繼承和多型,你真的都懂了嗎

ps:這裡重寫了toString方法才會是下面的輸出形式。上面就是呼叫了,那麼有的讀者可能就會問了,那你的eat方法還是private的呀,我還是不能呼叫啊,這裡我解釋一下,這是因為我是為了演示private的作用而在eat方法前面加的private,執行時我將它註釋掉了,至於實際上像eat這樣需要被類的呼叫者直接使用的方法,肯定是不能使用private修飾的,至於用什麼訪問許可權修飾這就是類的設計者根據日後業務的需要而決定了。

封裝的第一個作用就是為了不直接被外部使用,提高程式碼的安全性,第二個作用就是降低類的使用者的學習成本,不需要知道類的實現,只需要學會呼叫就好了

,封裝差不多就介紹完了,接下來聊聊繼承。

繼承

所謂繼承本質就是實現程式碼的複用,防止重複的程式碼多次書寫,當一個類繼承一個類的時候,該類中就會擁有另外一個類中的所有程式碼,舉個例子看下面程式碼

Java中的封裝、繼承和多型,你真的都懂了嗎

可以看到繼承的語法形式是

class 子類名 extends 父類名

,繼承類就是子類,也叫派生類,被繼承的類稱為父類,基類或者超類(名字一般不做區分,均可使用),語法形式很簡單,我們來聊聊其中的細節,首先

Java是單繼承的, 一個子類只能有一個父類

,但是一個子類可以當作另外一個類的父類,即可以B繼承A,然後C繼承B,程式碼如下,那麼B會擁有A中的程式碼,C會擁有A、B的程式碼。

Java中的封裝、繼承和多型,你真的都懂了嗎

下面講的普通類繼承知識都是基於父類是公開的並單獨位於一個.java檔案的。

我們定義一個這樣的Animal類當作父類:

Java中的封裝、繼承和多型,你真的都懂了嗎

當訪問使用private修飾的屬性時就會報錯,這個就是上面封裝的知識了,只能在定義的類中使用。

Java中的封裝、繼承和多型,你真的都懂了嗎

當去掉private不加任何修飾符時為包訪問許可權(對應上面的default範圍,至於default關鍵字的使用在介面當中會提到),當前包底下的類才能使用Animal中的屬性。

Java中的封裝、繼承和多型,你真的都懂了嗎

Java中的封裝、繼承和多型,你真的都懂了嗎

當使用protected修飾時,是可以在子類中呼叫的,那麼下面為什麼會報錯呢,那是因為呼叫的方式不對,這裡我們需要改變訪

問方式並使用到super關鍵字。

Java中的封裝、繼承和多型,你真的都懂了嗎

Java中的封裝、繼承和多型,你真的都懂了嗎

改為如下呼叫,

在子類中呼叫,並使用super關鍵字

,而不是透過例項化物件呼叫,上面那張圖除了提到包還提到了類,小夥伴們注意到了嗎?不記得的小夥伴們就往上翻再看看那張圖吧。

Java中的封裝、繼承和多型,你真的都懂了嗎

至於public沒啥好說的,哪都能用。上面呢介紹了繼承普通類的知識,現在我們來看看不太正常的類,抽象類,

抽象類是指被abstract修飾,包含抽象方法的類

,如下就是一個抽象類,首先是類名前面添加了abstract關鍵字,其次是其中包含了一個抽象方法,什麼是抽象方法,就是沒有被具體實現的方法,如下圖的work方法,沒有方法體,並被abstract修飾,不加的話會報錯,

被abstract修飾的類中可以沒有抽象方法,這是語法允許的(jdk1.8測出來的)

,但是建議同步使用,要麼既有abstract修飾類又有abstract方法,要麼都沒有,不然使用了abstract修飾類又不加abstract方法這不是鬧嗎,除非你不想這個類直接被例項化,注意一點,

abstract修飾的類不能直接被例項化

,需要被繼承之後透過子類呼叫父類的構造方法,對從父類繼承過來的欄位進行初始化,注意這些繼承過來的欄位和方法都到了子類中了,但是子類能不能使用和如何使用就和給的許可權(使用了什麼訪問修飾符限定)相關了,並沒有例項化產生一個父類物件,有些地方說會例項化一個父類物件這是不對的,說一個極端的說法,父類為抽象類你能例項化嗎?

Java中的封裝、繼承和多型,你真的都懂了嗎

Java中的封裝、繼承和多型,你真的都懂了嗎

當一個普通類繼承一個抽象類的時候

需要重寫抽象類的

所有

抽象方法,如果不想重寫的話就需要宣告為抽象類,看下面程式碼

Java中的封裝、繼承和多型,你真的都懂了嗎

Java中的封裝、繼承和多型,你真的都懂了嗎

繼承主要是為了程式碼的複用,減少程式碼的重複書寫和為多型打一個基礎,接下來我們聊聊多型

多型

多型是一種思想,是同一份程式碼,不同的傳參(子類)呼叫會產生不同的效果,絕對不是寫死的程式碼

多型是建立在繼承機制上的一種機制,想要了解多型就必須知道向上轉型,那麼什麼是向上轉型呢,所謂的向上轉型就是使用父類物件的引用,引用子類物件看下面程式碼

Java中的封裝、繼承和多型,你真的都懂了嗎

Java中的封裝、繼承和多型,你真的都懂了嗎

eacher是People的一個子類,使用People引用引用一個Teacher物件,向上轉型是自動發生的,不需要進行強制型別轉換,發生向上轉型一般有三種情況1。像上面程式碼一樣,讓父類引用直接引用子類物件時。2。子類作為函式呼叫時的實參,使用父類形參接收時。3。子類作為父類返回值函式的返回值時。

總的說就是父類引用引用了子類物件

Java中的封裝、繼承和多型,你真的都懂了嗎

紅色的框表示第二種,橘黃色的框表示第三種

ps:不難理解吧QAQ

與向上轉型對應的還有向下轉型,就是將父類物件賦值給子類引用,一般很少用的,就簡單地提一下吧,因為他發生條件比較嚴格,首先是不能直接強制型別轉換,看下面程式碼(已經將People類變成了類)

Java中的封裝、繼承和多型,你真的都懂了嗎

其次是需要父類引用引用子類的物件(發生過向上轉型),最後需要強制轉換為對應的子類物件,像下面這樣

Java中的封裝、繼承和多型,你真的都懂了嗎

ps:這東西用起來挺奇怪的,不太建議使用

到這裡相信你應該知道什麼叫做向上轉型了,但是這還不足以接觸多型,我們需要先來聊聊另外一個知識點,

動態繫結

,所謂動態繫結也叫執行時繫結,我們先來看看程式碼

Java中的封裝、繼承和多型,你真的都懂了嗎

Java中的封裝、繼承和多型,你真的都懂了嗎

先可以看到三個輸出,第一個輸出睡覺,第三個輸出教書沒問題吧,問題就出在第二個上面,我明明呼叫的是people的work方法,為什麼輸出的不是睡覺,而是教書呢?這就是發生了動態繫結,

所謂動態繫結就是使用父類引用引用子類物件然後(向上轉型)去呼叫父類和子類相同的方法

(返回值(構成父子類關係也可以,也就是協變型別),方法名,形參列表完全相同)換句話說也就是說在子類中重寫了父類的方法,這樣的重寫需要注意一些點,那就是子類重寫的方法的訪問許可權必須

不小於

父類的方法的許可權也就是說父類為public子類就必須為public因為public是最大的許可權,許可權對應上圖的

的個數√越多許可權越大,靜態方法不能重寫,被final修飾的方法(密封方法)不能重寫。ps:與動態繫結對應的還有靜態繫結,這裡就不多說了…好了,知道了向上轉型和動態繫結就可以瞭解多型了,看程式碼

Java中的封裝、繼承和多型,你真的都懂了嗎

是不是覺得很神奇,明明是指向了同一份程式碼卻列印了不同的結果,這就是多型,我不管你怎麼實現的方法,只要你有這個方法我就能幫你呼叫,並且這裡如果是子類物件會發生向上轉型,進而發生動態繫結,形成多型,上面是透過繼承來實現的多型,接下來我們再來講一個東西實現多型,介面

介面

那麼介面是什麼呢,介面也可以想象成一個類,但是它既然單獨出現,肯定說明它和類有有所不同,首先介面由interface關鍵字定義,並且其中的所有方法都預設為public abstract的,所有欄位都預設為public static final的,下面幾種定義方式並無區別。

Java中的封裝、繼承和多型,你真的都懂了嗎

然後類似與繼承,介面可以透過implements被實現,實現也很簡單,和繼承抽象類一樣重寫

所有

的抽象方法即可,同樣介面不

能被直接例項化。

Java中的封裝、繼承和多型,你真的都懂了嗎

有了上面的瞭解,我們來用介面實現多型,看下面程式碼,也和類實現多型沒什麼很大區別,也類似與發生了向上轉型和動態繫結,

實現介面和繼承類的一個很大區別就是一個類只能繼承一個類,但是一個類可以實現多個介面。

Java中的封裝、繼承和多型,你真的都懂了嗎

Java中的封裝、繼承和多型,你真的都懂了嗎

一些建議和小結

1。建議欄位的訪問許可權能給小絕不給大,能使用private修飾的欄位一定要用private,提高安全性。

2。繼承的層次不要太深,建議最多繼承三層,使用final修飾可以讓類無法被繼承。

3。抽象類的出現就是為了繼承之後重寫發生動態繫結。

4。能使用介面就不要使用抽象類,因為類只能單繼承,但是介面可以“多繼承”,更加的靈活。

5。多型的核心都是讓呼叫者不必關注物件的具體型別。 這是降低使用者使用成本的一種重要方式。

6。抽象類和介面的核心區別: 抽象類中可以包含普通方法和普通欄位, 這樣的普通方法和欄位可以被子類直接使用(不必重寫), 而介面中不能包含普通方法, 子類必須重寫所有的抽象方法。

7。介面中的方法和欄位定義都只寫必要部分,儘量簡潔像博主上面一樣

寫在最後的話

Java中的封裝、繼承和多型,你真的都懂了嗎

Top