2014-12-06 41 views
0

混亂比方說,我們有這兩個階級,一個主要的方法:約上溯造型和重載方法

public class Super { 
    public void f(double d){ 
     System.out.println("Super: f(double d)"); 
    } 
    public void f(int i){ 
     System.out.println("Super: f(int i)"); 
    } 
} 

public class Sub extends Super { 
    public void f(double d){ 
     System.out.println("Sub: f(double d)"); 
    } 

    public void f(float f){ 
     System.out.println("Sub: f(float f)"); 
    } 
} 

public class M { 
    public static void main(String[] args){ 
     Sub a = new Sub(); 
     a.f(1.5f); //output: "Sub: f(float f)" 

     Super b = new Sub(); 
     b.f(1.5f); //output: "Sub: f(double d)" 
    } 
} 

爲什麼第二個電話會導致Sub: f(double d)而不是像Sub: f(float f)的第一個?

當我添加

public void f(float f) { 
    System.out.println("Super: f(float f)"); 
} 

Super類,則輸出變爲Sub: f(float f)

鑑於這種行爲,我希望的工作流程是這樣的:

  1. 作爲a被upcasted到Super,類Super檢查的匹配方法
  2. 只有public void f(double d)被發現,所以浮子澆鑄到一個雙
  3. 現在方法public void f(double d)在更具體的類Sub看出並執行

這是正確的嗎?

+1

因爲沒有方法'f(float)'可以通過'Super'類型的引用獲得。 – 2014-12-06 21:01:15

回答

2

要理解此行爲,請注意選擇從編譯時調用一系列重載方法的方法始終執行。但是,在運行時執行方法調度

因此,在編譯時,只有double版本可見,但它將在運行時分派到子類的重寫版本。

1

的方法b.f(1.5f)在編譯時擡頭。它的實現將在運行時是更具體的(如果存在),但是在編譯時綁定了重載方法。

b由於是至少一個Super的唯一結論,編譯器可以推斷的是,該方法將是void f(double v)(因爲Super不具有float過載),使得一個被選擇。

然後在運行時實現是Sub類之一,由於動態綁定。