java多态具體表現形式有兩種:方法的重寫和方法的重載。先來看一段程式:
public class Main {
public static void main(String[] args) {
Base b=new Base();
Derived d=new Derived();
whichFoo(b, b);
whichFoo(b, d);
whichFoo(d, b);
whichFoo(d, d);
}
public static void whichFoo(Base arg1,Base arg2){
arg1.foo(arg2);
}
}
class Base{
public void foo(Base x){
System.out.println("Base.Base");
}
public void foo(Derived x){
System.out.println("Base.Derived");
}
}
class Derived extends Base{
public void foo(Base x){
System.out.println("Derived.Base");
}
public void foo(Derived x){
System.out.println("Derived.Derived");
}
}
它的輸出結果是:
Base.Base
Base.Base
Derived.Base
Derived.Base
這是因為在Java中,一個方法的參數在編譯階段常被靜态地綁定,在whichFoo方法中,形式參數arg2的類型是Base, 是以不管arg2實際引用的是什麼類型,arg1.foo(arg2)比對的foo都将是foo(Base),而要知道arg1引用的對象時,這是在運作階段由JVM決定的,稱為動态綁定。
再來看下面一段程式:
public class Main {
public static void main(String[] args) {
Father father=new Son();
System.out.println(father.age);
father.name();
father.age();
}
}
class Father{
public int age = ;
public static void name(){
System.out.println("father name");
}
public void age(){
System.out.println("father age:"+age);
}
}
class Son extends Father{
public int age = ;
public static void name(){
System.out.println("son name");
}
public void age(){
System.out.println("Son age:"+age);
}
}
輸出結果為:
60
father name
Son age:25
解釋如下:
當執行 Father father=new Son();發生了向上轉型,在編譯期間 father就是個Father對象,系統不知道實際上它是一個 Son對象,這得在運作期間由JVM判斷
在我們調用father.age的時候實際上,在處理java類中的成員變量時,并不是采用運作時綁定,而是一般意義上的靜态綁定,即調用的是Father類的age成員變量
在調用father.name()的時候,注意這是個static方法,java當中的方法final,static,private和構造方法是前期綁定,是以調用的是Father類中的name方法
在調用father.age()的時候,需要采用動态綁定,此時father會被解析成它實際的對象,即Son對象,是以實際調用的是Son.age()