多態:對象的多種形態
在程序中的體現表現在:父類的引用或者接口的引用指向了子類的對象
class Animal{
public void eat(){
//int num=0;
System.out.println("food");
}
}
class Dog extends Animal{
//int num=1;
public void eat(){
System.out.println("meat");
}
public void bark(){
System.out.println("汪汪");
}
}
class Monkey extends Animal{
//int num=2;
public void eat(){
System.out.println("banana");
}
}
public class duo {
public static void main(String[] args) {
Animal a=new Dog();//向上轉型,隱藏子類型,提高擴展性
Animal b=new Monkey();
method(a);
method(b);
}
private static void method(Animal a) {//定義共性類型的參數,既可以接受a,也可接受b,便於封裝,寫其他方法
a.eat();
//System.out.println(a.num);
//a.bark();//編譯不通過
/*if(a instanceof Dog){
Dog aa=(Dog)a;
aa.bark();
}*/
}
}
運行結果
meat
banana
當面對共性類型時,所有的子類對象都可以接受,優點:提高了代碼的擴展性
弊端:不能使用子類的特有方法,否則編譯不通過
前提:1.必須有關係(繼承,覆蓋)
2.通常有覆蓋
如果Dog類和Monkey類沒有對Animal中的eat方法重寫,運行結果會變成
food
food
什麼時候向上轉型?
如果不需要面對子類對象,使用父類的功能就可以完成操作(子類如果對功能重寫,則輸出結果是子類方法中的結果),就使用向上轉型
如果想使用子類的特有功能?
可以向下轉型。但是容易發生classCastException,只要轉換類型和對象類型不匹配就會發生類型錯誤,所以需加類型判斷
if(a instanceof Dog){
Dog aa=(Dog)a;
aa.bark();
}
多態中對成員的調用(當子父類中出現同名變量時)
1.成員變量
當子父類中出現同名變量時,多態調用,只看引用變量所屬的類。無論編譯或運行都看等號左邊
如上System.out.println(a.num);的運行結果是0 而不是1or2
2.成員函數
當子父類中出現同名函數時 ,多態調用,編譯看的是引用變量所屬類的方法,運行時看的是對象所屬類的方法。編譯看左,運行看右
3.靜態函數
出現一模一樣的靜態函數時,多態調用,只看引用變量所屬類的方法。無論編譯或運行都看等號左邊
真正調用靜態方法是不需要對象的,直接類名.函數名()