多态性,是面向對象的最後一個特征,也是最重要的特征,掌握多态性可以設計更好的程式結構。
實際上方法的重載就是一種多态性的展現:
方法名稱相同,根據傳入參數的類型或個數的不同完成的功能也不同。
另外一種多态性就是指的對象的多态性:
· 子類對象向父類對象轉型(向上轉型)
· 父類對象向子類對象轉型(向下轉型)
· 對象間的互相轉型問題
<b>強調:</b>
一個類絕對不能繼承一個已經實作好了的類。此處講解的時候隻是為了闡述概念,才使用了類與類的直接繼承,但是開發中此種類型的代碼肯定不存在。
觀察以下程式,初步認識對象的轉型:
class A{
public void fun1(){
System.out.println("A --> public void fun1(){}") ;
}
public void fun2(){
this.fun1() ;
};
class B extends A{
System.out.println("B --> public void fun1(){}") ;
public void fun3(){
System.out.println("B --> public void fun3(){}") ;
以上代碼可以發現,子類B,繼承了父類A,同時在子類中覆寫了類A中的fun1方法,也增加了自己新的fun3方法。
System.out.println("A1 --> public void fun1(){}") ;
System.out.println("B1 --> public void fun1(){}") ;
System.out.println("B2 --> public void fun3(){}") ;
public class Demo10{
public static void main(String args[]){
A a = new B() ;
a.fun1() ;
a.fun2() ;
以上代碼,無論是直接使用子類,還是子類向父類轉型,發現最終結果調用的都是被子類覆寫過的方法。
向上轉型的關系:隻要發生了向上轉型,則一切的操作方法以子類為标準。
如果向上轉型完成之後,那麼一定可以把父類對象變為子類對象。但是此時就需要強制了。
B b = (B)a ;
b.fun1() ;
b.fun2() ;
現在觀察以下代碼:
public class Demo11{
<b> A a = new A() ;</b>
<b> B b = (B)a ;</b>
<b>java.lang.ClassCastException</b><b>:</b>
為類型轉換異常。兩個沒有任何關系的對象直接進行轉型了,就出現此錯誤。
<b>注意:</b>
如果要進行向下轉型之前,首先必須建立關系,即:必須先發生向上轉型之後,才可以進行向下轉型。為了建立關系。
<b>對象多态性所帶來的好處?</b>
對象多态性在傳遞參數上可以展現出其優點,下面看兩組代碼,第一組是沒有使用對象多态性的時候:
class C extends A{
System.out.println("C1 --> public void fun1(){}") ;
System.out.println("C2 --> public void fun3(){}") ;
public class Demo12{
fun(new B()) ;
fun(new C()) ;
// 定義一個方法,此方法可以接收A的子類對象
public static void fun(B b){
public static void fun(C c){
c.fun2() ;
如果代碼按以上格式編寫會有那些問題?
· 每增加一個子類,就要增加一個方法,是以可以發現代碼重複修改。
如果此時使用了對象多态性的概念,則代碼可以修改為以下結構(所有的操作方法以被子類覆寫過的方法為标準操作):
public class Demo13{
// 不管有多少個子類,都用父類對象接收,因為可以自動發生向上轉型關系
public static void fun(A a){
<b>感覺到一點:</b>在繼承關系中,父類的設計是最重要的,隻要父類把功能定義好了,則所有代碼都好寫。
<b>新的要求:</b>
現在希望可以對程式的功能稍微有一些擴充,判斷,如果傳入的是B類對象,則可以調用fun3方法,如果傳入的是C類對象,也可以調用C類的fun3方法。
要完成此功能,肯定要使用向上轉型。
要完成此功能,必須對傳入對象的類型進行判斷,判斷此對象到底是屬于那個類的執行個體。
instanceof關鍵字完成:
· 功能:判斷一個對象是否是某個類的執行個體,傳回boolean
· 文法:對象 instanceof 類
public class Demo14{
if(<b>a instanceof B</b>){
B b = (B)a ;
b.fun3() ;
}
if(<b>a instanceof C</b>){
C c = (C)a ;
c.fun3() ;
<b>轉型原則:</b>
在轉型之前最好先判斷一下一個對象是否是某個類的執行個體,判斷通過之後在進行向下轉型操作。
轉型概念清楚之後就可以利用此概念完善抽象類與接口。
本文轉自 李興華 51CTO部落格,原文連結:http://blog.51cto.com/lixinghua/91245,如需轉載請自行聯系原作者