生活随笔
收集整理的這篇文章主要介紹了
Java中的向下转型与向上转型
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
java轉型問題其實并不復雜,只要記住一句話:父類引用指向子類對象。
什么叫父類引用指向子類對象,且聽我慢慢道來.
從2個名詞開始說起:向上轉型(upcasting)、向下轉型(downcasting).
舉個例子:有2個類,Father是父類,Son類繼承自Father。
Father f1 = newSon();?? // 這就叫upcasting (向上轉型)
// 現在f1引用指向一個Son對象
Son s1 =(Son)f1;?? // 這就叫downcasting (向下轉型)
// 現在f1還是指向Son對象
第2個例子:
Father f2 = newFather();
Son s2 =(Son)f2;??????//出錯,子類引用不能指向父類對象
你或許會問,第1個例子中:Son s1 = (Son)f1;問什么是正確的呢。
很簡單因為f1指向一個子類對象,Father f1 = newSon(); 子類s1引用當然可以指向子類對象了。
而f2 被傳給了一個Father對象,Father f2 = newFather();子類s1引用不能指向父類對象。
總結:
1。父類引用指向子類對象,而子類引用不能指向父類對象。
2。把子類對象直接賦給父類引用叫upcasting向上轉型,向上轉型不用強制轉換。
?????如:Father f1 = new Son();
3。把指向子類對象的父類引用賦給子類引用叫向下轉型(downcasting),要強制轉換。
?? 如:f1就是一個指向子類對象的父類引用。把f1賦給子類引用s1即 Son s1 =(Son)f1;
??????????其中f1前面的(Son)必須加上,進行強制轉換。
一、向上轉型。
通俗地講即是將子類對象轉為父類對象。此處父類對象可以是接口。
1,向上轉型中的方法調用。
看下面代碼:
[java] package?com.wensefu.others;??public?class?Animal?{????????????public?void?eat(){??????????System.out.println("animal?eatting...");??????}??}??class?Bird?extends?Animal{????????????public?void?eat(){??????????System.out.println("bird?eatting...");??????}????????????public?void?fly(){????????????????????System.out.println("bird?flying...");??????}??}??class?Main{????????????public?static?void?main(String[]?args)?{????????????????????Animal?b=new?Bird();?//向上轉型??????????b.eat();???????????//!?error:?b.fly();?b雖指向子類對象,但此時丟失fly()方法??????????dosleep(new?Male());??????????dosleep(new?Female());??????}????????????public?static?void?dosleep(Human?h)?{??????????h.sleep();??????}??}????????????????????????????
package?com.wensefu.others;??
public?class?Human?{??????public?void?sleep()?{??????????System.out.println("Human?sleep..");??????}??}??class?Male?extends?Human?{??????@Override??????public?void?sleep()?{??????????System.out.println("Male?sleep..");??????}??}??class?Female?extends?Human?{??????@Override??????public?void?sleep()?{??????????System.out.println("Female?sleep..");??????}??}????????????????????????????
注意這里的向上轉型:
?????? Animal b=newBird(); //向上轉型
??????b.eat();
此處將調用子類的eat()方法。原因:b實際指向的是Bird子類,故調用時會調用子類本身的方法。
需要注意的是向上轉型時b會遺失除與父類對象共有的其他方法。如本例中的fly方法不再為b所有。
2,向上轉型的好處。
看上面的代碼,
???public static void dosleep(Human h) {
??????h.sleep();
??? }
這里以父類為參數,調有時用子類作為參數,就是利用了向上轉型。這樣使代碼變得簡潔。不然的話,
如果dosleep以子類對象為參數,則有多少個子類就需要寫多少個函數。這也體現了JAVA的抽象編程思想。
二、向下轉型。
與向上轉型相反,即是把父類對象轉為子類對象。
看下面代碼:
package?com.wensefu.other1;??
public?class?Girl?{??????public?void?smile(){??????????System.out.println("girl?smile()...");??????}??}??class?MMGirl?extends?Girl{????????????@Override??????public?void?smile()?{????????????????????System.out.println("MMirl?smile?sounds?sweet...");??????}??????public?void?c(){??????????System.out.println("MMirl?c()...");??????}??}??class?Main{????????????public?static?void?main(String[]?args)?{????????????????????Girl?g1=new?MMGirl();?//向上轉型??????????g1.smile();????????????????????MMGirl?mmg=(MMGirl)g1;?//向下轉型,編譯和運行皆不會出錯??????????mmg.smile();??????????mmg.c();??????????????????????????????Girl?g2=new?Girl();??//??????MMGirl?mmg1=(MMGirl)g2;?//不安全的向下轉型,編譯無錯但會運行會出錯??//??????mmg1.smile();??//??????mmg1.c();????????????if(g2?instanceof?MMGirl){??????????????MMGirl?mmg1=(MMGirl)g2;???????????????mmg1.smile();??????????????mmg1.c();??????????}????????????????}??}??
Girl g1=new MMGirl(); //向上轉型
??????g1.smile();
??????MMGirl mmg=(MMGirl)g1; //向下轉型,編譯和運行皆不會出錯
這里的向下轉型是安全的。因為g1指向的是子類對象。
而
Girl g2=new Girl();
MMGirl mmg1=(MMGirl)g2; //不安全的向下轉型,編譯無錯但會運行會出錯
運行出錯:
Exception in thread "main"java.lang.ClassCastException: com.wensefu.other1.Girl
??? atcom.wensefu.other1.Main.main(Girl.java:36)
如代碼所示,可以通過instanceof來防止出現異常。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的Java中的向下转型与向上转型的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。