Java編程分享,Java子類與父類轉(zhuǎn)換

Java編程分享,Java子類與父類轉(zhuǎn)換

天津卓眾教育      2022-04-20 04:28:01     22

Java編程分享,Java子類與父類轉(zhuǎn)換,在使用Java的多態(tài)機(jī)制時(shí),常常使用的一個(gè)特性便是子類和父類之間的對(duì)象轉(zhuǎn)換。從子類向父類的轉(zhuǎn)換稱為向上轉(zhuǎn)換(upcasting),通

課程價(jià)格 請(qǐng)咨詢

上課時(shí)段: 授課校區(qū):

詳細(xì)介紹

在使用Java的多態(tài)機(jī)制時(shí),常常使用的一個(gè)特性便是子類和父類之間的對(duì)象轉(zhuǎn)換。從子類向父類的轉(zhuǎn)換稱為向上轉(zhuǎn)換(upcasting),通過向上轉(zhuǎn)換,我們能夠在編寫程序時(shí)采用通用程序設(shè)計(jì)的思想,在需要使用子類對(duì)象的時(shí)候,通過把變量定義為父類型,我們可以通過一個(gè)變量,使用該父類型的所有子類型實(shí)例;從父類型向子類型的轉(zhuǎn)換稱為向下轉(zhuǎn)換(downcasting),通過向下轉(zhuǎn)換,我們能在必要的時(shí)候,將父類型變量轉(zhuǎn)換成子類型變量,使用一些通過子類型才能夠使用的方法。以下是我對(duì)于對(duì)象轉(zhuǎn)換的一些個(gè)人理解,如有不對(duì),歡迎指正,虛心向大神們請(qǐng)教。

首先是從子類向父類的向上轉(zhuǎn)換。向上轉(zhuǎn)換比較直觀,總是能夠?qū)⒁粋€(gè)子類的實(shí)例轉(zhuǎn)換為一個(gè)父類的對(duì)象,從繼承鏈的角度,這個(gè)特性很容易理解:繼承是一種“是一種”的關(guān)系,從父類派生出的子類,我們都能理解為,子類總是父類的一個(gè)實(shí)例。比如說,F(xiàn)ruit類派生出了Orange類,Apple類,Orange和Apple都是Fruit;Animal類派生出了Tiger類和Lion類,Tiger和Lion都是Animal。因此,從子類向父類的轉(zhuǎn)換不需要什么限制,只需直接將子類實(shí)例賦值給父類變量即可,這也是Java中的多態(tài)的實(shí)現(xiàn)機(jī)制。

//Test.javapublic?class?Test?{????public?static?void?main(String?args[])?{????????Animal?tiger?=?new?Tiger();????????Animal?lion?=?new?Lion();????}}?class?Animal?{????String?name;????Animal()?{????????name?=?"animal";????}????Animal(String?name)?{????????this.name?=?name;????}}class?Tiger?extends?Animal?{????Tiger()?{????????super("tiger");????}}class?Lion?extends?Animal?{????Lion()?{????????super("lion");????}}

然而從父類向子類的向下轉(zhuǎn)換就稍微復(fù)雜一些了。在講述向下轉(zhuǎn)換之前,也許有些剛學(xué)java的朋友會(huì)有點(diǎn)不解為什么要使用向下轉(zhuǎn)換,使用多態(tài)和動(dòng)態(tài)綁定機(jī)制通過父類型變量使用子變量不就可以了么(比如我就曾對(duì)此感到疑惑)。這就要考慮到,在繼承關(guān)系中,有一些方法是不適合由父類定義并由子類繼承并重寫的,有些方法是子類特有的,不應(yīng)該通過繼承得到,且子類可能也會(huì)有自己特有的成員變量,那么在使用多態(tài)機(jī)制的時(shí)候,若我們要通過父類型變量使用到這些子類特有的方法和屬性的話,就需要將服類型變量轉(zhuǎn)換成對(duì)應(yīng)的子類型變量。一個(gè)典型例子便是標(biāo)準(zhǔn)庫(kù)中的數(shù)據(jù)類型包裝類:Integer類,Double類,Long類等,它們都繼承自Number類,且它們都有一個(gè)方法叫做compareTo用于比較兩個(gè)同樣的類型。然而這個(gè)方法是這些子類通過實(shí)現(xiàn)Comparable接口來實(shí)現(xiàn)的,在Number類中并沒有該方法的實(shí)現(xiàn),因此若要通過Number類型變量來使用compareTo方法,就要先將Number類轉(zhuǎn)換成子類的對(duì)象。

從父類向子類的轉(zhuǎn)換就有限制了。首先,父類變量向子類轉(zhuǎn)換必須通過顯式強(qiáng)制類型轉(zhuǎn)換,采取和向上轉(zhuǎn)換相同的直接賦值方式是不行的,;并且,當(dāng)把一個(gè)父類型變量實(shí)例轉(zhuǎn)換為子類型變量時(shí),必須確保該父類變量是子類的一個(gè)實(shí)例,從繼承鏈的角度來理解這些原因:子類一定是父類的一個(gè)實(shí)例,然而父類卻不一定是子類的實(shí)例;比如說,F(xiàn)ruit未必是Orange,它可能是Apple;Animal也不一定是Tiger,它可能是Lion。用代碼來解釋一下:

Animal?tiger?=?new?Tiger();Animal?lion?=?new?Lion();

在前面向上轉(zhuǎn)換的代碼示例當(dāng)中,main方法中的這兩行代碼,意思就是父類型變量tiger是子類Tiger的一個(gè)實(shí)例,lion是Lion的一個(gè)實(shí)例。

也就是說,如果要把tiger轉(zhuǎn)換為Tiger類型,必須保證tiger本身是Tiger的一個(gè)實(shí)例,在上例中,如果要把tiger轉(zhuǎn)換成Lion類型,或是把Lion類型轉(zhuǎn)換為Tiger類型,都是行不通的,在運(yùn)行時(shí),這會(huì)拋出一個(gè)運(yùn)行異常ClassCastException,表示類轉(zhuǎn)換異常。因此,在進(jìn)行父類向子類的轉(zhuǎn)換時(shí),一個(gè)好的習(xí)慣是通過instanceof運(yùn)算符來判斷父類變量是否是該子類的一個(gè)實(shí)例:

Tiger?t?=?null;if(tiger?instanceof?Tiger)????t?=?(Tiger)tiger;

如果要通過父類調(diào)用子類變量的方法,那么要注意要將父類型變量和強(qiáng)制轉(zhuǎn)換用括號(hào)括起來:

Number?i?=?new?Integer(3);System.out.println(????((Integer)i).compareTo(new?Integer(4))??????????????????);

因?yàn)槌蓡T訪問運(yùn)算符.的優(yōu)先級(jí)大于類型轉(zhuǎn)換,所以要用括號(hào)括起來保證類型轉(zhuǎn)換先于成員訪問進(jìn)行運(yùn)算。

前面說到用instanceof判斷父類是否是子類的一個(gè)實(shí)例是一個(gè)好習(xí)慣,如果不養(yǎng)成這個(gè)習(xí)慣的話很容易出問題,請(qǐng)看下面這段代碼:

Animal?animal?=?new?Tiger();Lion?lion?=?(Lion)tiger;

前面說到,這段代碼會(huì)在運(yùn)行時(shí)拋出ClassCastException異常,然而,這段代碼卻是能夠編譯成功的。原因是因?yàn)?,Java編譯器并沒有聰明到能夠在編譯階段就知道父類型變量是哪一個(gè)子類的實(shí)例,所以,將animal轉(zhuǎn)換為L(zhǎng)ion類型的代碼:(Lion)animal是能夠編譯通過的,即使事實(shí)上我們能看到animal是Tiger的一個(gè)實(shí)例,因?yàn)锳nimal類型確實(shí)能轉(zhuǎn)換成Lion類型,所以這條語句是合法的。所以,如果沒有使用instanceof防止不同子類型之間的對(duì)象轉(zhuǎn)換,而又不能指望編譯器檢查出這種轉(zhuǎn)換邏輯錯(cuò)誤的話,就很容易犯錯(cuò)了。

如果目的是把以上的,tiger與lion的共同屬性值賦值,可以使用以下方式: 

BeanUtils.copyProperties(tiger,lion);?

以上就是天津卓眾教育java培訓(xùn)機(jī)構(gòu)的小編針對(duì)“Java編程分享,Java子類與父類轉(zhuǎn)換”的內(nèi)容進(jìn)行的回答,希望對(duì)大家有所幫助,如有疑問,請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。

培訓(xùn)啦提醒您:交易時(shí)請(qǐng)核實(shí)對(duì)方資質(zhì),對(duì)于過大宣傳或承諾需謹(jǐn)慎!任何要求預(yù)付定金、匯款等方式均存在風(fēng)險(xiǎn),謹(jǐn)防上當(dāng)。