學習Java之如何正確地向上轉(zhuǎn)型與向下轉(zhuǎn)型
一. 類型轉(zhuǎn)型
將一個類型轉(zhuǎn)換成另一個類型的過程被稱為類型轉(zhuǎn)換。 我們所說的對象類型轉(zhuǎn)換,一般是指兩個存在繼承關系的對象,而不是任意類型的對象。如果兩個類型之間沒有繼承關系,就不允許進行類型轉(zhuǎn)換,否則會拋出強制類型轉(zhuǎn)換異常(java.lang.ClassCastException)。
Java語言允許某個類型的引用變量引用子類的實例,而且可以對這個引用變量進行類型轉(zhuǎn)換。Java中引用類型之間的類型轉(zhuǎn)換(前提是兩個類是直接或間接的父子關系)主要有兩種,分別是向上轉(zhuǎn)型(upcasting)和向下轉(zhuǎn)型(downcasting) 。
我們先來看下面這張圖:
貓、狗、牛、羊都是動物,所以”動物“是父類,貓狗牛羊是具體的子類。我們可以說貓是動物,狗是動物,牛是動物,羊是動物,這個結(jié)論肯定沒錯!但如果我們說,動物是貓,動物是狗,動物是牛,動物是羊,這個結(jié)論一定正確嗎?那可就不一定了。子類肯定符合父類類型,但反之,父類不一定符合子類類型!
接下來分別對向上轉(zhuǎn)型和向下轉(zhuǎn)型進行講解。
二. 向上轉(zhuǎn)型
1. 概念
所謂的向上轉(zhuǎn)型,就是父類引用指向子類的對象,也就是把子類對象直接賦給父類引用變量,此時不用強制轉(zhuǎn)換。比如我們說貓是動物,狗是動物,牛是動物,羊是動物,這就是把子類當成父類來用。父類是子類的上級,我們直接把子類向上提拔轉(zhuǎn)型了。
2. 特點
向上轉(zhuǎn)型具有如下特點:
- 編譯類型取決于=號左邊,運行類型取決于=號右邊;
- 子類可以調(diào)用父類的所有成員,但需遵守訪問權(quán)限;
- 父類不能調(diào)用子類的特有成員;
- 最終的運行效果取決于子類的具體實現(xiàn)。
3. 語法
向上轉(zhuǎn)型的基本語法如下所示:
//左側(cè)是父類引用變量,右側(cè)是創(chuàng)建的子類對象,我們可以把它當作父類使用 父類類型 引用名 = new 子類類型();
4. 案例
接下來我們通過一個案例來演示向上轉(zhuǎn)型該如何實現(xiàn)。
/** * @author 一一哥Sun * 定義父類---向上與向下轉(zhuǎn)型 */ public interface Animal { //叫 public void speak(); } //Dog類實現(xiàn)Animal接口 public class Dog implements Animal { @Override public void speak() { System.out.println("狗子:汪汪"); } } //Cat類實現(xiàn)Animal接口 public class Cat implements Animal { @Override public void speak() { System.out.println("貓子:喵喵"); } } //定義一個測試類 public class AnimalTest { public static void main(String[] args) { //向上轉(zhuǎn)型 //父類引用dog變量,指向子類對象new Dog(); //動物 = 狗;以下代碼的意思就是”狗是動物“ Animal dog=new Dog(); //向上轉(zhuǎn)型后,可以使用父類Animal中的屬性和方法。 dog.speak(); //Animal animal=new Cat();效果等同于如下兩行代碼: Cat cat=new Cat(); Animal animal=cat; animal.speak(); } }
我們在進行向上轉(zhuǎn)型時,可以寫成Animal animal=new Cat(); Animal animal=cat;
的形式。就是先創(chuàng)建出cat對象,然后再將cat對象賦值給Animal類型的變量,這樣就實現(xiàn)了向上轉(zhuǎn)型。因為Animal是父級類型,Cat是子級類型,Cat是Animal的子類,所以可以直接將cat變量賦值給animal,這就是向上轉(zhuǎn)型。但這種寫法比較繁瑣,我們通常是直接采用Animal cat=new Cat();
的形式,簡潔明了。
我們之所以可以實現(xiàn)向上轉(zhuǎn)型,主要是因為兩個類型之間是父子關系。比如在本例中,向上轉(zhuǎn)型就等于說”貓是動物,狗是動物“,因為貓狗都是動物的子類,所以這個結(jié)論是確定無誤的。
三. 向下轉(zhuǎn)型
1. 概念
向下轉(zhuǎn)型則反之,也就是一個已經(jīng)向上轉(zhuǎn)型的子類對象指向父類引用。 向下轉(zhuǎn)型后,可以調(diào)用子類類型中所有的成員。向下轉(zhuǎn)型時,必須進行強制類型轉(zhuǎn)換。因為父類擁有的成員,子類肯定會有,但子類擁有的成員,父類不一定有。
但要注意,如果父類的引用對象指向的是子類對象,則向下轉(zhuǎn)型時是安全的,即編譯時不會出現(xiàn)錯誤。但如果父類的引用對象是父類本身,那么在向下轉(zhuǎn)型的過程中是不安全的,雖然編譯時不會出錯,但在運行過程中會出現(xiàn)強制類型轉(zhuǎn)換異常。我們可以使用instanceof運算符來避免出現(xiàn)強制類型轉(zhuǎn)換異常。
2. 特點
向下轉(zhuǎn)型具有如下特點:
- 只能強制轉(zhuǎn)換父類的引用,不能強制轉(zhuǎn)換父類的對象;
- 父類的引用必須指向子類目標類型的對象;
- 向下轉(zhuǎn)型后,父類可以調(diào)用子類類型中的所有成員。
3. 語法
向下轉(zhuǎn)型的基本語法如下所示:
//向下轉(zhuǎn)型使用強制類型轉(zhuǎn)換的格式,將父類引用類型轉(zhuǎn)換為子類引用類型 子類類型 引用名 = (子類類型) 父類引用;
4. 案例
接下來我們在上面的案例基礎之上,對代碼進行改造,在Cat類中增加一個新的方法。
public class Cat implements Animal { @Override public void speak() { System.out.println("貓子:喵喵"); } //給其他動物打招呼 public void helloAnimal(Animal animal) { //向下轉(zhuǎn)型,將父類型轉(zhuǎn)為子類型。 //此時有可能會出現(xiàn)ClassCastException類型轉(zhuǎn)換異常,因為子類一定屬于父類的一員,但父類不一定屬于子類。 //我們說“貓是動物”一定沒問題,但如果說“動物是貓”,這個結(jié)論未必正確。所以把“動物強轉(zhuǎn)成貓”的過程中,有可能會出現(xiàn)異常。 //只有兩者之間具有明確的父子關系時才能進行強轉(zhuǎn),否則就會出現(xiàn)類型轉(zhuǎn)換異常。 //向下轉(zhuǎn)型時需要進行類型強轉(zhuǎn) Cat cat=(Cat) animal; //向下轉(zhuǎn)型后,可以使用子類Cat中的屬性和方法。 cat.speak(); } } //測試類 public class AnimalTest { public static void main(String[] args) { Animal animal=new Cat(); animal.speak(); Cat cat=new Cat(); //這里我們傳參時,既可以傳遞animal,也可以傳遞cat,但不能傳遞dog類型,否則會出現(xiàn)java.lang.ClassCastException: //因為class com.yyg.convert.Dog cannot be cast to class com.yyg.convert.Cat。狗不能被轉(zhuǎn)成貓 //cat2.helloAnimal(dog); cat.helloAnimal(animal); //Dog dog = new Dog(); //這里就會編譯出錯,不允許把Dog對象類型轉(zhuǎn)換成Cat對象類型 //Cat cat = (Cat)dog; } }
向下轉(zhuǎn)型就是將父類型轉(zhuǎn)為子類型,但要注意,此時有可能會出現(xiàn)ClassCastException類型轉(zhuǎn)換異常,因為子類一定屬于父類的一員,但父類不一定屬于子類。我們說“貓是動物”一定沒問題,但如果說“動物是貓”,這個結(jié)論未必正確。所以把“動物強轉(zhuǎn)成貓”的過程中,有可能會出現(xiàn)異常。只有兩者之間具有明確的父子關系時才能進行強轉(zhuǎn),否則就會出現(xiàn)類型轉(zhuǎn)換異常。
就比如上面的案例中,我們傳參時,既可以傳遞animal,也可以傳遞cat,但不能傳遞dog類型,否則會出現(xiàn)java.lang.ClassCastException,因為class com.yyg.convert.Dog cannot be cast to class com.yyg.convert.Cat,狗類不能被轉(zhuǎn)成貓類。
四. 結(jié)語
至此,就把類型轉(zhuǎn)換給大家介紹完了,我們來看看類型轉(zhuǎn)換的要點吧::
- 向上轉(zhuǎn)型是父類引用指向子類的對象,不必強制類型轉(zhuǎn)換 ;
- 向下轉(zhuǎn)型是子類對象指向父類引用,必須進行強制類型轉(zhuǎn)換;
- 可以強制向下轉(zhuǎn)型最好借助instanceOf進行類型判斷;
以上就是學習Java之如何正確地向上轉(zhuǎn)型與向下轉(zhuǎn)型的詳細內(nèi)容,更多關于Java向上轉(zhuǎn)型與向下轉(zhuǎn)型的資料請關注腳本之家其它相關文章!
相關文章
Java中的權(quán)重算法(如Dubbo的負載均衡權(quán)重)詳解
這篇文章主要介紹了Java中的權(quán)重算法(如Dubbo的負載均衡權(quán)重)詳解,負載均衡,其含義就是指將負載進行平衡、分攤到多個操作單元上進行運行,例如FTP服務器、Web服務器、企業(yè)核心應用服務器和其它主要任務服務器等,從而協(xié)同完成工作任務,需要的朋友可以參考下2023-08-08如何利用NetworkInterface獲取服務器MAC地址
今天介紹一種通用的跨平臺的操作方式,那就是JDK自帶的NetworkInterface接口,該接口在JDK1.4已經(jīng)出現(xiàn),但是功能比較少,JDK1.6之后新增了不少新功能,比較不錯2013-08-08springboot不同環(huán)境使用不同配置文件打包方式
這篇文章主要介紹了springboot不同環(huán)境使用不同配置文件打包方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11Spring?MVC中@Controller和@RequestMapping注解使用
這篇文章主要介紹了Spring?MVC中@Controller和@RequestMapping注解使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02Spring Boot 2.X整合Spring-cache(讓你的網(wǎng)站速度飛起來)
這篇文章主要介紹了Spring Boot 2.X整合Spring-cache(讓你的網(wǎng)站速度飛起來),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-09-09