1. 程式人生 > 實用技巧 >Java 多型和instanceof的使用

Java 多型和instanceof的使用

先建立一個父類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則相反;