這篇文章帶給大家的內容是關於Java向轉型和向下轉型的使用介紹(附程式碼),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
1 向轉型(子類別轉換成父類別)
範例:
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(); //向上转型 a.a1(); } }
如果執行C,輸出的是Superclass 還是Childrenclass?不是你原來預期的Superclass,而是Childrenclass。這是因為a實際上指向的是子類別物件。當然,你不用擔心,Java虛擬機會自動精確地辨識出究竟該呼叫哪個具體的方法。不過,由於向上轉型,a物件會遺失和父類別不同的方法,例如b1()。有人可能會提出疑問:這不是多此一舉嗎?我們完全可以這樣寫:
B a = new B();
a.a1();
#確實如此!但這樣就喪失了面向抽象的程式設計特色,降低了可擴展性。其實,不僅如此,向上轉型還可以減輕程式設計工作量。來看下面的顯示器類別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"); } } 现在有一个MyMonitor类。假设没有向上转型,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(); } } 可能你已经意识到上述代码有很多重复代码,而且也不易维护。有了向上转型,代码可以更为简洁: 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(Monitor monitor) { //父类实例作为参数 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"); } }
2 向下轉型(父類別轉型成子類別)
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(); // 向上转型 a1.aMthod(); // 调用父类aMthod(),a1遗失B类方法bMethod1()、bMethod2() B b1 = (B) a1; // 向下转型,编译无错误,运行时无错误 b1.aMthod(); // 调用父类A方法 b1.bMethod1(); // 调用B类方法 b1.bMethod2(); // 调用B类方法 A a2 = new A(); B b2 = (B) a2; // 向下转型,编译无错误,运行时将出错 b2.aMthod(); b2.bMethod1(); b2.bMethod2(); } } 从上面的代码我们可以得出这样一个结论:向下转型需要使用强制转换。运行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
其實B b2 = (B) a2處的向下轉型程式碼後的註解已經提示你將發生執行時間錯誤。為什麼前一句向下轉型代碼可以,而後一句代碼卻出錯?這是因為a1指向一個子類別B的對象,所以子類別B的實例物件b1當然也可以指向a1。而a2是父類對象,子類對象b2不能指向父類對象a2。那麼如何避免在執行向下轉型時發生運行時ClassCastException異常?使用5.7.7節學過的instanceof就可以了。我們修改一下C類別的程式碼:
A a2 = new A(); if (a2 instanceof B) { B b2 = (B) a2; b2.aMthod(); b2.bMethod1(); b2.bMethod2(); }
這樣處理後,就不用擔心型別轉換時發生ClassCastException異常了。
#以上是Java向上轉型和向下轉型的使用介紹(附程式碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!