Java 多型和instanceof的使用
阿新 • • 發佈:2021-01-03
先建立一個父類Animal類:
public class Animal{ public void move(){ System.out.println("動物可以移動"); } }
建立子類Cat類:
public class Cat extends Animal{ public void move(){ //繼承Animal類,然後重寫move方法; System.out.println("cat can run"); } public void catcatch(){ //這是cat特有的方法 System.out.println("cat can catch mouse"); } }
再建立一個子類Bird類:
public class Bird extends Animal{ public void move(){ System.out.println("Bird can fly"); } }
在AnimalTest測試類中:
/* 多型的基礎語法使用 */ public class AnimalTest{ public static void main(String[] args){ Animal a = new Animal(); a.move(); Cat c= new Cat(); c.move(); Bird b = new Bird(); b.move(); Animal c1 = new Cat(); //向上轉型 ,可以建立 , Cat就是一個Animal //c1.catcatch(); //不能編譯通過 , 在編譯階段,只會在Animal.class中找catcatch方法,沒有找到 Cat x = (Cat)c1; //當需要訪問子類中特有的方法時, 此時就需要向下型別轉換 x.catcatch();//向下型別轉換的風險 /* Animal b1 = new Bird(); Cat y = (Cat)b1; //編譯階段不會報錯,在編譯階段只識別到b1是一個Animal型別; y.catcatch(); //但是在執行階段就會報錯,java.lang.ClassCastException:型別轉化異常,因為Bird和Cat沒有繼承關係; */ Animal b2 = new Bird(); //為了規避這種風險,可以使用instanceof進行判斷,只有b2是一個Cat型別時,才會進行向下轉型 if(b2 instanceof Cat){ Cat z = (Cat)b2; z.catcatch(); } } }
在示例向下轉型過程中:
在編譯是,只識別到b1是一個一個Animal型別,然後向下轉型為Cat,而Animal和Cat之前存在著繼承關係,就可以進行向下轉型,所以編譯沒有問題;
而在執行態時,在堆記憶體中實際建立了Bird物件,Bird物件與Cat物件沒有繼承關係,所以就不能進行型別轉化;就會發生java.lang.ClassCastException:型別轉化異常;
為了解決型別轉化異常可以使用instanceof在執行時進行判斷:
(1)instanceof可以在執行期動態判斷引用指向物件的型別;
(2)instanceof語法結構(引用 instanceof 型別);
(3)instanceof返回值為false/true;
(4)b2是一個引用,b2變數儲存的記憶體地址指向了堆記憶體中物件,(b2 instanceof Cat)為true,則表示是一個Cat型別,為false則相反;