向下轉型的使用 Java的多態性: 父類指向子類的聲明 Animal animal = new Dog()//Dog()重寫了父類Animal 有了對象的多態性以後,記憶體實際上載入的是==子類==的屬性和方法,但是由於變數聲明為==父類類型==,導致編譯時只能調用父類的屬性和方法,子類特有的屬性方法 ...
向下轉型的使用
Java的多態性:
父類指向子類的聲明
Animal animal = new Dog()//Dog()重寫了父類Animal
- 有了對象的多態性以後,記憶體實際上載入的是子類的屬性和方法,但是由於變數聲明為父類類型,導致編譯時只能調用父類的屬性和方法,子類特有的屬性方法不能調用。
- 調用子類特有的屬性和方法:向下轉型,使用強制類型轉換符。
- 向下轉型有風險,使用強轉可能出現ClassCastException異常。為了避免出現異常,此時應該使用instanceof關鍵字。
向下轉型在開發中使用較少,一般只會用父類中存在的屬性方法。
因為多態性是運行時行為,但是在編譯的時候就已經載入了子類的屬性和方法,但是用不了子類的特有方法,例如Dog子類類特有的方法liugou(),編譯就會報錯。
//父類Animal:
class Animal{
public void eat(){
System.out.println("吃吃吃");
}
public void shout(){
System.out.println("叫叫叫");
}
}
//子類Dog
class Dog extends Animal{
@Override
public void shout() {
System.out.println("汪汪汪");
}
public void eat(){
System.out.println("吃狗糧");
}
//子類特有方法lugou()
public void liugou(){
System.out.println("遛狗");
}
}
class Cat extends Animal{
@Override
public void shout(){
System.out.println("喵喵喵");
}
public void eat(){
System.out.println("吃魚");
}
public void hand(){
System.out.println("手賤");
}
}
調用子類特有方法報錯
public class AnimalTest {
public static void main(String[] args){
AnimalTest test = new AnimalTest();
test.func(new Dog());
}
public void func(Animal animal){
animal.eat();
animal.liugou();//子類特有方法報錯
}
}
向下轉型(強制類型轉換):
public void func(Animal animal){
animal.eat();
Dog dog = (Dog) animal;//使用強制類型轉換,不報錯
dog.liugou();
}
向下轉型的風險(編譯時可以通過,運行時出現ClassCastException異常):
public void func(Animal animal){
animal.eat();
Dog dog = (Dog) animal;
Cat cat = (Cat) animal;
cat.hand();//animal並沒有載入cat的屬性和方法,編譯正常但是運行時錯誤
dog.liugou();
}
instanceof關鍵字的使用方法:
a instanceof A:判斷對象a是否是A的實例,如果是返回true,否則返回flase。
if(animal instanceof Cat){
Cat cat = (Cat) animal;
cat.hand();//animal不是Cat的實例,因此hand()不執行
}