Java多態(tài)實現(xiàn)原理詳細梳理總結
一、概述
引入
多態(tài)是繼封裝、繼承之后,面向對象的第三大特性。生活中,比如跑的動作,小貓、小狗和大象,跑起來是不一樣的。再比如飛的動作,昆蟲、鳥類和飛機,飛起來也是不一樣的。可見,同一行為,通過不同的事物,可以體現(xiàn)出來的不同的形態(tài)。多態(tài),描述的就是這樣的狀態(tài)。
定義
多態(tài): 是指同一行為,具有多個不同表現(xiàn)形式。
二、多態(tài)的體現(xiàn)
多態(tài)體現(xiàn)的格式:
父類類型 變量名 = new 子類對象;
變量名.方法名();
父類類型:指子類對象繼承的父類類型,或者實現(xiàn)的父接口類型。
代碼如下:
Fu f = new Zi(); f.method();
當使用多態(tài)方式調用方法時,首先檢查父類中是否有該方法,如果沒有,則編譯錯誤;如果有,執(zhí)行的是子類重寫后方法。
代碼如下:
定義父類:
public abstract class Animal {
public abstract void eat();
}定義子類:
class Cat extends Animal {
public void eat() {
System.out.println("吃魚??");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨頭??");
}
}定義測試類:
public class Test {
public static void main(String[] args) {
// 多態(tài)形式,創(chuàng)建對象
Animal a1 = new Cat();
// 調用的是 Cat 的 eat
a1.eat();
// 多態(tài)形式,創(chuàng)建對象
Animal a2 = new Dog();
// 調用的是 Dog 的 eat
a2.eat();
}
}三、多態(tài)的好處
實際開發(fā)的過程中,父類類型作為方法形式參數(shù),傳遞子類對象給方法,進行方法的調用,更能體現(xiàn)出多態(tài)的擴展性與便利
定義父類:
public abstract class Animal {
public abstract void eat();
}定義子類:
class Cat extends Animal {
public void eat() {
System.out.println("吃魚??");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨頭??");
}
}定義測試類:
public class Test {
public static void main(String[] args) {
// 多態(tài)形式,創(chuàng)建對象
Cat c = new Cat();
Dog d = new Dog();
// 調用showCatEat
showCatEat(c);
// 調用showDogEat
showDogEat(d);
/**
以上兩個方法, 均可以被showAnimalEat(Animal a)方法所替代
而執(zhí)行效果一致
*/
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();
}
}由于多態(tài)特性的支持,showAnimalEat方法的Animal類型,是Cat和Dog的父類類型,父類類型接收子類對象,當然可以把Cat對象和Dog對象,傳遞給方法。
當eat方法執(zhí)行時,多態(tài)規(guī)定,執(zhí)行的是子類重寫的方法,那么效果自然與showCatEat、showDogEat方法一致,
所以showAnimalEat完全可以替代以上兩方法。
不僅僅是替代,在擴展性方面,無論之后再多的子類出現(xiàn),我們都不需要編寫showXxxEat方法了,直接使用
showAnimalEat都可以完成。
所以,多態(tài)的好處,體現(xiàn)在,可以使程序編寫的更簡單,并有良好的擴展。
四、引用類型轉換
多態(tài)的轉型分為向上轉型與向下轉型兩種:
向上轉型
向上轉型:多態(tài)本身是子類類型向父類類型向上轉換的過程,這個過程是默認的。當父類引用指向一個子類對象時,便是向上轉型。
使用格式:
父類類型 變量名 = new 子類類型();
如:Animal a = new Cat();
向下轉型
向下轉型:父類類型向子類類型向下轉換的過程,這個過程是強制的。
一個已經向上轉型的子類對象,將父類引用轉為子類引用,可以使用強制類型轉換的格式,便是向下轉型。
使用格式:
子類類型 變量名 = (子類類型) 父類變量名;
如:Cat c =(Cat) a;
為什么要轉型
當使用多態(tài)方式調用方法時,首先檢查父類中是否有該方法,如果沒有,則編譯錯誤。也就是說,不能調用子類擁有,而父類沒有的方法。編譯都錯誤,更別說運行了。這也是多態(tài)給我們帶來的一點"小麻煩"。所以,想要調用子類特有的方法,必須做向下轉型。
轉型演示,代碼如下:
定義類:
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃魚??");
}
public void catchMouse() {
System.out.println("抓老鼠??");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨頭??");
}
public void watchHouse() {
System.out.println("看家??");
}
}定義測試類:
public static void main(String[] args) {
// 向上轉型
Animal a = new Cat();
a.eat(); // 調用的是 Cat 的 eat
// 向下轉型
Cat c = (Cat)a;
c.catchMouse(); // 調用的是 Cat 的 catchMouse
}轉型的異常
轉型的過程中,一不小心就會遇到這樣的問題,請看如下代碼:
public class Test {
public static void main(String[] args) {
// 向上轉型
Animal a = new Cat();
a.eat(); // 調用的是 Cat 的 eat
// 向下轉型
Dog d = (Dog)a;
d.watchHouse(); // 調用的是 Dog 的 watchHouse 【運行報錯】
}
}這段代碼可以通過編譯,但是運行時,卻報出了 ClassCastException ,類型轉換異常!這是因為,明明創(chuàng)建了Cat類型對象,運行時,當然不能轉換成Dog對象的。這兩個類型并沒有任何繼承關系,不符合類型轉換的定義。為了避免ClassCastException的發(fā)生,Java提供了 instanceof 關鍵字,給引用變量做類型的校驗,格式如下:
變量名 instanceof 數(shù)據(jù)類型
如果變量屬于該數(shù)據(jù)類型,返回true。
如果變量不屬于該數(shù)據(jù)類型,返回false。
所以,轉換前,我們最好先做一個判斷,代碼如下:
public class Test {
public static void main(String[] args) {
// 向上轉型
Animal a = new Cat();
a.eat(); // 調用的是 Cat 的 eat
// 向下轉型
if (a instanceof Cat){
Cat c = (Cat)a;
c.catchMouse(); // 調用的是 Cat 的 catchMouse
} else if (a instanceof Dog){
Dog d = (Dog)a;
d.watchHouse(); // 調用的是 Dog 的 watchHouse
}
}
}到此這篇關于Java多態(tài)實現(xiàn)原理詳細梳理總結的文章就介紹到這了,更多相關Java 多態(tài)內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
微服務鏈路追蹤Spring Cloud Sleuth整合Zipkin解析
這篇文章主要為大家介紹了微服務鏈路追蹤Spring Cloud Sleuth整合Zipkin解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02
SpringBoot異步任務實現(xiàn)下單校驗庫存的項目實踐
在開發(fā)中,異步任務應用的場景非常的廣泛,本文主要介紹了SpringBoot異步任務實現(xiàn)下單校驗庫存的項目實踐,具有一定的參考價值,感興趣的可以了解一下2023-09-09

