更新時間:2019-09-16 16:18:32 來源:動力節(jié)點 瀏覽3369次
今天動力節(jié)點java培訓機構(gòu)小編為大家介紹“java對象類向上轉(zhuǎn)型和向下轉(zhuǎn)型詳解”,希望通過此文大家能夠掌握java對象類向上轉(zhuǎn)型和向下轉(zhuǎn)型詳解,下面就隨小編一起看看吧。
向上轉(zhuǎn)型
我們在現(xiàn)實中常常這樣說:這個人會唱歌。在這里,我們并不關(guān)心這個人是黑人還是白人,是成人還是小孩,也就是說我們更傾向于使用抽象概念“人”。再例如,麻雀是鳥類的一種(鳥類的子類),而鳥類則是動物中的一種(動物的子類)。我們現(xiàn)實中也經(jīng)常這樣說:麻雀是鳥。這兩種說法實際上就是所謂的向上轉(zhuǎn)型,通俗地說就是子類轉(zhuǎn)型成父類。這也符合Java提倡的面向抽象編程思想。來看下面的代碼:
package a.b;
public class A {
public void a1() {
System.out.println("Superclass");
}
}
A的子類B:
package a.b;
public class B extends A {
public void a1() {
System.out.println("Childrenclass"); //覆蓋父類方法
}
public void b1(){} //B類定義了自己的新方法
}
C類:
package a.b;
public class C {
public static void main(String[] args) {
A a = new B(); //向上轉(zhuǎn)型
a.a1();
}
}
如果運行C,輸出的是Superclass 還是Childrenclass?不是你原來預期的Superclass,而是Childrenclass。這是因為a實際上指向的是一個子類對象。當然,你不用擔心,Java虛擬機會自動準確地識別出究竟該調(diào)用哪個具體的方法。不過,由于向上轉(zhuǎn)型,a對象會遺失和父類不同的方法,例如b1()。有人可能會提出疑問:這不是多此一舉嗎?我們完全可以這樣寫:
B a = new B();
a.a1();
確實如此!但這樣就喪失了面向抽象的編程特色,降低了可擴展性。其實,不僅僅如此,向上轉(zhuǎn)型還可以減輕編程工作量。來看下面的顯示器類Monitor:
package a.b;
public class Monitor{
public void displayText() {}
public void displayGraphics() {}
}
液晶顯示器類LCDMonitor是Monitor的子類:
package a.b;
public class LCDMonitor extends Monitor {
public void displayText() {
System.out.println("LCD display text");
}
public void displayGraphics() {
System.out.println("LCD display graphics");
}
}
陰極射線管顯示器類CRTMonitor自然也是Monitor的子類:
package a.b;
public class CRTMonitor extends Monitor {
public void displayText() {
System.out.println("CRT display text");
}
public void displayGraphics() {
System.out.println("CRT display graphics");
}
}
等離子顯示器PlasmaMonitor也是Monitor的子類:
package a.b;
public class PlasmaMonitor extends Monitor {
public void displayText() {
System.out.println("Plasma display text");
}
public void displayGraphics() {
System.out.println("Plasma display graphics");
}
}
現(xiàn)在有一個MyMonitor類。假設(shè)沒有向上轉(zhuǎn)型,MyMonitor類代碼如下:
package a.b;
public class MyMonitor {
public static void main(String[] args) {
run(new LCDMonitor());
run(new CRTMonitor());
run(new PlasmaMonitor());
}
public static void run(LCDMonitor monitor) {
monitor.displayText();
monitor.displayGraphics();
}
public static void run(CRTMonitor monitor) {
monitor.displayText();
monitor.displayGraphics();
}
public static void run(PlasmaMonitor monitor) {
monitor.displayText();
monitor.displayGraphics();
}
}
可能你已經(jīng)意識到上述代碼有很多重復代碼,而且也不易維護。有了向上轉(zhuǎn)型,代碼可以更為簡潔:
package a.b;
public class MyMonitor {
public static void main(String[] args) {
run(new LCDMonitor()); //向上轉(zhuǎn)型
run(new CRTMonitor()); //向上轉(zhuǎn)型
run(new PlasmaMonitor()); //向上轉(zhuǎn)型
}
public static void run(Monitor monitor) { //父類實例作為參數(shù)
monitor.displayText();
monitor.displayGraphics();
}
}
我們也可以采用接口的方式,例如:
package a.b;
public interface Monitor {
abstract void displayText();
abstract void displayGraphics();
}
將液晶顯示器類LCDMonitor稍作修改:
package a.b;
public class LCDMonitor implements Monitor {
public void displayText() {
System.out.println("LCD display text");
}
public void displayGraphics() {
System.out.println("LCD display graphics");
}
}
CRTMonitor、PlasmaMonitor類的修改方法與LCDMonitor類似,而MyMonitor可以不不作任何修改。
可以看出,向上轉(zhuǎn)型體現(xiàn)了類的多態(tài)性,增強了程序的簡潔性。
向下轉(zhuǎn)型
子類轉(zhuǎn)型成父類是向上轉(zhuǎn)型,反過來說,父類轉(zhuǎn)型成子類就是向下轉(zhuǎn)型。但是,向下轉(zhuǎn)型可能會帶來一些問題:我們可以說麻雀是鳥,但不能說鳥就是麻雀。來看下面的例子:
A類:
package a.b;
public class A {
void aMthod() {
System.out.println("A method");
}
}
A的子類B:
package a.b;
public class B extends A {
void bMethod1() {
System.out.println("B method 1");
}
void bMethod2() {
System.out.println("B method 2");
}
}
C類:
package a.b;
public class C {
public static void main(String[] args) {
A a1 = new B(); // 向上轉(zhuǎn)型
a1.aMthod(); // 調(diào)用父類aMthod(),a1遺失B類方法bMethod1()、bMethod2()
B b1 = (B) a1; // 向下轉(zhuǎn)型,編譯無錯誤,運行時無錯誤
b1.aMthod(); // 調(diào)用父類A方法
b1.bMethod1(); // 調(diào)用B類方法
b1.bMethod2(); // 調(diào)用B類方法
A a2 = new A();
B b2 = (B) a2; // 向下轉(zhuǎn)型,編譯無錯誤,運行時將出錯
b2.aMthod();
b2.bMethod1();
b2.bMethod2();
}
}
從上面的代碼我們可以得出這樣一個結(jié)論:向下轉(zhuǎn)型需要使用強制轉(zhuǎn)換。運行C程序,控制臺將輸出:
Exception in thread "main" java.lang.ClassCastException: a.b.A cannot be cast to a.b.B at
a.b.C.main(C.java:14)
A method
A method
B method 1
B method 2
其實黑體部分的向下轉(zhuǎn)型代碼后的注釋已經(jīng)提示你將發(fā)生運行時錯誤。為什么前一句向下轉(zhuǎn)型代碼可以,而后一句代碼卻出錯?這是因為a1指向一個子類B的對象,所以子類B的實例對象b1當然也可以指向a1。而a2是一個父類對象,子類對象b2不能指向父類對象a2。那么如何避免在執(zhí)行向下轉(zhuǎn)型時發(fā)生運行時ClassCastException異常?我們修改一下C類的代碼:
A a2 = new A();
if (a2 instanceof B) {
B b2 = (B) a2;
b2.aMthod();
b2.bMethod1();
b2.bMethod2();
}
這樣處理后,就不用擔心類型轉(zhuǎn)換時發(fā)生ClassCastException異常了。
以上就是動力節(jié)點java培訓機構(gòu)小編介紹的“java對象類向上轉(zhuǎn)型和向下轉(zhuǎn)型詳解”的內(nèi)容,希望對大家有幫助,更多java最新資訊請繼續(xù)關(guān)注動力節(jié)點java培訓機構(gòu)官網(wǎng),每天會有精彩內(nèi)容分享與你。
相關(guān)免費視頻教程推薦
java多態(tài)視頻教程下載——多態(tài)中的向下轉(zhuǎn)型:http://www.dabaquan.cn/xiazai/2599.html