2009-11-05 93 views
2

根據java,實例方法解析基於參數的運行時類型。實例方法和變量情況下的java繼承解析

但是,雖然解析實例變量,它使用不同的方法,如下所示。程序的

輸出是..

Child 
Parent 
ParentNonStatic 

這裏首先輸出基於運行時類型的說法,但第三輸出的是沒有的。

能有人解釋一下嗎?

public class Child extends Parent { 

     public static String foo = "Child"; 
     public String hoo = "ChildNonStatic"; 

     private Child() { 
      super(1); 
     } 

     @Override 
     String please() { 
      return "Child"; 
     } 

     public static void main(String[] args) { 
      Parent p = new Parent(); 
      Child c = new Child(); 

      //Resolving method 
      System.out.println(((Parent) c).please()); 

      //Resolving Static Variable 
      System.out.println(((Parent) c).foo); 

      //Resolving Instance Variable 
      System.out.println(((Parent) c).hoo); 
     } 
    } 
class Parent { 

    public static String foo = "Parent"; 
    public String hoo = "ParentNonStatic"; 

    public Parent(int a) { 
    } 

    public Parent() { 
    } 

    String please() { 
     return "Tree"; 
    } 
} 

回答

1

在Java中,你實際上並沒有「中投」。 Java實際上並沒有任何事情,當你要求一個強制轉換,除非檢查對象是否可以轉換爲該類型,因此爲什麼強制轉換可以拋出「ClassCastException」。

雖然編譯器理解了強制轉換並因此使用它們來驗證方法調用是否合適。

對於靜態字段,編譯器實際上刪除了任何實例變量,並根據返回類型是否通過類引用該字段。

Parent p = new Parent(); 
Child c = new Child(); 
Parent pc = new Child(); 

System.out.println(c.foo); // will print Child 
System.out.println(p.foo); // will print Parent 
System.out.println(pc.foo); // will print Parent 
System.out.println(((Child)pc).foo) // will print Child 

字段似乎以相同的方式工作。

我想概括地說,java在方法和靜態綁定上對字段進行動態綁定。

0

域之間沒有以同樣的方式方法被覆蓋。通過將c投射到Parent,您指示「.hoo」指的是Parent上的「hoo」字段,而不是Child上的「hoo」字段。 (以更加技術上正確的方式,現場訪問不是多態的。)

5

當您上傳對象時,實際上並未更改所引用項目的內容,只是您對待的方式它。因此,當你將c上傳到父母並請求()時,你可以在Parent上調用please(),但是動態類型仍然是一個孩子,所以真正被調用的是孩子中被覆蓋的版本並打印「Child」。

當你上傳c並引用foo時,你沒有進行函數調用。編譯器可以在編譯時確定你所指的是什麼。在這種情況下,具有父類型的對象的字段foo。字段和靜態字段不會被覆蓋。相反,它們是隱藏的。你實際上最終用這個upcast做的事情是幫助Java選擇隱藏的版本(來自Parent的版本)而不是來自孩子的版本。同樣,你可以用hoo獲得父級的版本。

這裏的Java教程的一些信息:http://java.sun.com/docs/books/tutorial/java/IandI/hidevariables.html