2012-03-24 31 views
2

說,有以下示例:在Object o =「」的幫助下創建的對象的類型;

class Super { 
    public int i = 3; 
    public void m(Object o) { 
     System.out.println("Object " + i); 
    } 
    public void m(String o) { 
     System.out.println("String " + i); 
    } 
} 

public class Sub extends Super { 
    public Sub() { 
     i = 5; 
    } 
    public static void main(String[] args) { 
     Super s = new Sub(); 
     Object o = ""; 
     s.m(o); 
     s.m(""); 
    } 
} 

這段代碼的結果是:

Object 5 
String 5 

但我認爲這將是:

String 5 
String 5 

不要引號設置字符串作爲這個對象的類型?在引用的幫助下,肯定會有一些投射爲字符串的情況,所以我對這個基本示例有點困惑。提前致謝。

+0

你是否分享了所有的代碼?我沒有看到名爲sb的變量。 – Simeon 2012-03-24 19:41:23

+0

應該是's',對不起。 – 2012-03-24 19:42:55

回答

3

該方法的類型是在編譯時確定的,而不是在運行時確定的。 dynamic dispatch僅適用於「參數」this - 對於諸如java的static typing語言中沒有參數的動態分派。

編譯「據法權產」應調用哪一種方法,由於oObject型的 - 它的動產m(Object) - 它沒有辦法知道的是,動態類型的o實際上是一個String

如果您有興趣 - 在某些情況下解決此問題的常用方法是使用visitor design pattern

在您的具體情況,以「力」的m(String)激活你應該使用m(o.toString())

+0

感謝您的好解釋。 – 2012-03-24 19:47:13

+0

@JohnDoe:你很受歡迎,我希望這一點很明確。如果您需要更多關於「靜態類型」和「動態類型」之間的區別的說明,請詢問。如果您已經知道其中的差異 - 我認爲這個答案應該已經爲您解決了問題,但是如果您還不清楚,歡迎您提供更多詳細信息。 – amit 2012-03-24 19:50:49

+0

是的,我確實知道動態和靜態類型之間的區別(實際上,我認爲靜態類型更容易理解),但在上面的示例中不知何故錯過了這一點。我一定會看到訪客模式。 – 2012-03-24 23:23:04

1

您將對象聲明爲Object,因此其類型爲Object。 Java中的類型是強大且靜態的,所以當你聲明一個類型爲Type的對象時,它的類型將是終生的。

如果你希望它是你必須使用一個toString方法或鑄造(String)o

2

sb.m(o)一個字符串,你調用M()與對象引用,所以Java選擇是超載。 Java不會選擇比通過它的引用類型更具體的過載。儘管如此,它會繼承傳承鏈。假設你沒有m(String o),調用sb.m("Hello")仍然是合法的,但它會調用對象版本。

如果你要做sb.m((String) o),你會得到你的預期行爲。

0

你向下轉換的String對象。你在做什麼與此類似。

public class Sub extends Super { 
    public Sub() { 
     i = 5; 
    } 
    public static void main(String[] args) { 
     Super s = new Sub(); 
     Object o = ""; 
     System.out.println("Object Type = " + o.getClass().getName()); 
     s.m(o); 
     s.m((Object)""); 
    } 
} 
相關問題