2013-04-29 55 views
4

我觀察到當我們從一個多態對象調用一個變量時,它調用父變量,但是當我們調用具有相同多態對象的方法時,它會調用子方法。爲什麼這是Java中多態的行爲?爲什麼Java不以相同的方式處理多態變量和方法?變量綁定VS多態中的方法綁定

class Parent{ 

    int age =10; 

    public void showAge(){ 

     System.out.println("Parent Age:"+age); 
    } 
} 

class ChildOne extends Parent{ 

    int age = 20; 

    public void showAge(){ 

     System.out.println("child one age:"+age); 
    } 
} 

class ChildTwo extends Parent{ 

    int age = 30; 

    public void showAge(){ 

     System.out.println("Child Two Age:"+age); 
    } 
} 
public class Test{ 


    public static void main(String[] args) { 

     Parent parentChildOne = new ChildOne(); 
     System.out.println("parentChildOne.age: "+parentChildOne.age); 
     parentChildOne.showAge(); 

     Parent parentChildTwo = new ChildTwo(); 
     System.out.println("parentChildTwo.age: "+parentChildTwo.age); 
     parentChildTwo.showAge(); 

    } 
} 

這裏是輸出:

parentChildOne.age: 10 
child one age:20 
parentChildTwo.age: 10 
Child Two Age:30 
+1

變量不是多態的。 – Keppil 2013-04-29 07:59:44

+0

好的比較。我自己試了一下。假設超類和子類有一個名爲相同的實例字段 - var。然後投射物體將改變結果。 「((Superclass)subclassObj).var」給出超類的實例字段var。所以我認爲Java中的變量名稱是由引用類型解析的,而不是它們引用的實際obj類型。 – 2015-01-20 23:42:17

+0

而方法名稱是動態綁定,它使用實際的obj類型。所以它就是多態。 – 2015-01-20 23:53:55

回答

1

首先記住Your variables are not polymorphic和接下來的高潮就是你的這點

Parent parentChildOne = new ChildOne(); 
    Parent parentChildTwo = new ChildTwo(); 

見,當你試圖調用使用Parent parentChildOne的方法,那麼它應該叫孩子的方法,因爲它是應該被調用,並根據多態性進行覆蓋。

現在再看到Parent parentChildOne同一個對象變量,現在這裏是沒有什麼用的多態性,但JVM是與shadowing
概念現在正在處理呢?所以這就是爲什麼他們倆都呈現
請按照本教程的shadowing in java

+0

好現在我可以瞭解他們的行爲差異。良好的例子:)謝謝很多 – Despicable 2013-04-29 08:08:57

0

parentChildOneparentChildTwo的類型爲Parent。因此,您正在打印Parentage。與showAge()方法相同,但age的值被子類遮蔽。

0

他們真正的行爲請參閱評論,

class Parent{ 

    int age =10; 

    public void showAge(){ 

     System.out.println("Parent Age:"+age); 
    } 
} 

class ChildOne extends Parent{ 
    //when you extends Parent the inherited members are like 
    //and initialized into the default constructor 
    // int super.age =10; 
    int age = 20; 

    public void showAge(){ 

     System.out.println("child one age:"+age); 
    } 
} 

class ChildTwo extends Parent{ 
    //when you extends Parent the inherited members are like 
    //and initialized into the default constructor 
    // int super.age =10; 
    int age = 30; 

    public void showAge(){ 

     System.out.println("Child Two Age:"+age); 
    } 
} 
public class Test{ 


    public static void main(String[] args) { 

     Parent parentChildOne = new ChildOne(); 
      // when we call like this, goes to the parent type of the variable instead of object. 
     System.out.println("parentChildOne.age: "+parentChildOne.age); 
     parentChildOne.showAge(); 

     Parent parentChildTwo = new ChildTwo(); 
      // when we call like this, goes to the parent type of the variable instead of object. 
     System.out.println("parentChildTwo.age: "+parentChildTwo.age); 
     parentChildTwo.showAge(); 

    } 
}