面向對象的最後一個主要特性----多態

今天的知識是我在這裡的基礎班學習的最後一天的內容了,所以請你一定要堅持把今天的學完,再決定要不要繼續,加油吧!

面向對象的最後一個主要特性----多態

今天主要是多態、內部類

多態

多態是繼封裝、繼承之後,面向對象的第三大特性。

定義

多態: 是指同一行為,具有多個不同表現形式。

前提【重點】

1. 繼承或者實現【二選一】

2. 方法的重寫【意義體現:不重寫,無意義】

3. 父類引用指向子類對象【格式體現】

多態體現的格式:

面向對象的最後一個主要特性----多態

父類類型:指子類對象繼承的父類類型,或者實現的父接口類型。

當使用多態方式調用方法時,首先檢查父類中是否有該方法,如果沒有,則編譯錯誤;如果有,執行的是子類重寫後方法。

代碼如下:

面向對象的最後一個主要特性----多態

面向對象的最後一個主要特性----多態

多態的好處

實際開發的過程中,父類類型作為方法形式參數,傳遞子類對象給方法,進行方法的調用,更能體現出多態的擴展性與便利。

代碼如下

面向對象的最後一個主要特性----多態

面向對象的最後一個主要特性----多態

定義測試類:

public class Test {
public static void main(String[] args) {
// 多態形式,創建對象
Cat c = new Cat();
Dog d = new Dog();
// 調用showCatEat
showCatEat(c);
// 調用showDogEat
showDogEat(d);
/*
以上兩個方法, 均可以被showAnimalEat(Animal a)方法所替代
而執行效果一致

*/
showAnimalEat(c);
showAnimalEat(d);
}
public static void showCatEat (Cat c){
c.eat();
}
public static void showDogEat (Dog d){
d.eat();
}
public static void showAnimalEat (Animal a){
a.eat();
}
}

由於多態特性的支持,showAnimalEat方法的Animal類型,是Cat和Dog的父類類型,父類類型接收子類對象,當然可以把Cat對象和Dog對象,傳遞給方法。

當eat方法執行時,多態規定,執行的是子類重寫的方法,那麼效果自然與showCatEat、showDogEat方法一致,所以showAnimalEat完全可以替代以上兩方法。

不僅僅是替代,在擴展性方面,無論之後再多的子類出現,我們都不需要編寫showXxxEat方法了,直接使用showAnimalEat都可以完成。

所以,多態的好處,體現在,可以使程序編寫的更簡單,並有良好的擴展。

引用類型轉換

多態的轉型分為向上轉型與向下轉型兩種:

面向對象的最後一個主要特性----多態

面向對象的最後一個主要特性----多態

為什麼要轉型

當使用多態方式調用方法時,首先檢查父類中是否有該方法,如果沒有,則編譯錯誤。也就是說,不能調用子類擁有,而父類沒有的方法。編譯都錯誤,更別說運行了。這也是多態給我們帶來的一點"小麻煩"。所以,想要調用子類特有的方法,必須做向下轉型。

轉型演示,代碼如下:

面向對象的最後一個主要特性----多態

面向對象的最後一個主要特性----多態

面向對象的最後一個主要特性----多態

轉型的異常

轉型的過程中,一不小心就會遇到這樣的問題,請看如下代碼:

面向對象的最後一個主要特性----多態

這段代碼可以通過編譯,但是運行時,卻報出了 ClassCastException ,類型轉換異常!這是因為,明明創建了Cat類型對象,運行時,當然不能轉換成Dog對象的。這兩個類型並沒有任何繼承關係,不符合類型轉換的定義。

為了避免ClassCastException的發生,Java提供了 instanceof 關鍵字,給引用變量做類型的校驗,格式如下:

面向對象的最後一個主要特性----多態

面向對象的最後一個主要特性----多態

interface作為方法參數

當接口作為方法的參數時,需要傳遞什麼呢?對,其實都是它的子類對象。 ArrayList 類我們並不陌生,查看API我們發現,實際上,它是 java.util.List 接口的實現類。所以,當我們看見List 接口作為參數或者返回值類型時,當然可以將ArrayList 的對象進行傳遞或返回。

面向對象的最後一個主要特性----多態

面向對象的最後一個主要特性----多態

面向對象的最後一個主要特性----多態

面向對象的最後一個主要特性----多態

這是今天的第二大塊知識

內部類

什麼是內部類

將一個類A定義在另一個類B裡面,裡面的那個類A就稱為內部類,B則稱為外部類。

成員內部類

成員內部類 :定義在類中方法外的類。

面向對象的最後一個主要特性----多態

在描述事物時,若一個事物內部還包含其他事物,就可以使用內部類這種結構。比如,汽車類Car 中包含發動機類Engine ,這時, Engine 就可以使用內部類來描述,定義在成員位置。

面向對象的最後一個主要特性----多態

訪問特點

內部類可以直接訪問外部類的成員,包括私有成員。

外部類要訪問內部類的成員,必須要建立內部類的對象。

創建內部類對象格式:

外部類名.內部類名 對象名 = new 外部類型().new 內部類型();

面向對象的最後一個主要特性----多態

面向對象的最後一個主要特性----多態

面向對象的最後一個主要特性----多態

內部類仍然是一個獨立的類,在編譯之後會內部類會被編譯成獨立的.class文件,但是前面冠以外部類的類名和$符號 。

比如,Person$Heart.class

匿名內部類

匿名內部類 :是內部類的簡化寫法。它的本質是一個帶具體實現的 父類或者父接口的 匿名的 子類對象。

開發中,最常用到的內部類就是匿名內部類了。以接口舉例,當你使用一個接口時,似乎得做如下幾步操作,

1. 定義子類

2. 重寫接口中的方法

3. 創建子類對象

4. 調用重寫後的方法

我們的目的,最終只是為了調用方法,那麼能不能簡化一下,把以上四步合成一步呢?匿名內部類就是做這樣的快捷方式。

前提

匿名內部類必須繼承一個父類或者實現一個父接口。

面向對象的最後一個主要特性----多態

使用方式

以接口為例,匿名內部類的使用,代碼如下:

面向對象的最後一個主要特性----多態

創建匿名內部類,並調用:

通常在方法的形式參數是接口或者抽象類時,也可以將匿名內部類作為參數傳遞。代碼如下:

面向對象的最後一個主要特性----多態

面向對象的最後一個主要特性----多態

到此基礎班的知識學完了,從明天開始更新後續的知識,學如逆水行舟不進則退,既然學了,就堅持到底學習完。


分享到:


相關文章: