2010-05-17 60 views
4

如果我有兩個類x和y,都擴展類w。和x實現接口z。如果我有方法doSomething(w對象)和doSomething(x對象),如果我調用doSomething(x)會發生什麼?多態性和接口

編輯: 即時通訊在java上實現這個,更具體地在android上。我問這個問題,因爲當doSomething()被調用時,實現特定接口的一些類通常會做同樣的事情。但我想單獨列出一些特殊情況。

+1

你能更具體嗎?你是指鑽石問題還是別的什麼? – wheaties 2010-05-17 17:20:38

+2

這可能取決於所討論的編程語言,但通常編譯器會選擇具有最佳擬合參數類型的方法,在本例中爲採用'x對象'的方法。 – 2010-05-17 17:21:35

+2

你爲什麼不試試?什麼壞事都會發生在你身上。 :) – Simon 2010-05-17 17:24:23

回答

1

比方說,你有

w object1 = new x(); 
x object2 = new x(); 

傳遞object1將執行和傳球對象2 doSomething(x object)

P.S:當然這取決於語言(談論C#)

P.P.S:添加參數名稱以使其更清晰

+0

-1:這個答案假定doSomething(w)和doSomething(x)不是*都在x上實現。 – 2010-05-17 17:29:51

+0

w和x是類型,而不是變量。現在應該清楚了。 :) – Simon 2010-05-17 17:30:46

+0

@Simon:正式指出。 – 2010-05-17 17:34:04

-2

你不能有兩個不同的方法具有相同的簽名。其不明確的代碼,編譯器不會編譯和解釋器會引發錯誤。

+2

簽名是不同的。第一類是x類,第二類是y類。這是一個完全合法的問題。 – Joseph 2010-05-17 17:21:36

2

這取決於你使用的語言。例如,在C#中,它將使用doSomething(x對象)而不是doSomething(w對象)。

但是,如果你把它強制轉換爲W,則它會使用DoSomething的(W對象)是這樣的:

doSomething((w) someObjectOfX); 

doSomething(someObjectOfX as w); 
1

在C#中,編譯器將選擇合適的方法取決於在變量的聲明類型上,而不是存儲在其中的實際類型。

請注意,下面的代碼聲明W是一個類,並構造它的一個實例。如果您使用W作爲界面,並刪除其聲明和構造,則您將獲得與下面程序xy相同的行爲,在這種情況下界面或類W並不重要。

讓我告訴你區別:

using System; 

namespace SO2851194 
{ 
    class W { } 
    class X : W { } 
    class Y : W { } 

    class Program 
    { 
     static void Main() 
     { 
      W w = new W(); 
      X x = new X(); 
      Y y = new Y(); 

      doSomething(w); 
      doSomething(x); 
      doSomething(y); 
     } 

     static void doSomething(W w) 
     { 
      Console.Out.WriteLine("w"); 
     } 

     static void doSomething(X x) 
     { 
      Console.Out.WriteLine("x"); 
     } 
    } 
} 

這裏我聲明瞭三個變量,W類型,X,並且Y,並調用doSomething傳遞三個變量,一個接一個。該程序的輸出是:

w 
x 
w 

如所預期的,編譯器會選擇具有最佳擬合參數類型的方法中,並在x變量的情況下,它有可利用的對象的方法鍵入X

然而,由於類繼承,我們可以改變變量的聲明,但要構造的對象類型,所以改變這樣的代碼:

W w = new W(); 
W x = new X(); // Notice, changed variable type to W 
W y = new Y(); // but keep constructing X and Y 

這就是現在輸出:

w 
w 
w 

因此,x變量包含X類型的對象並沒有考慮到它,編譯器從變量類型中選擇了該方法,而不是它的內容。

在C#4.0中,你現在有dynamic類型,所以再次更改代碼:

dynamic w = new W(); 
dynamic x = new X(); 
dynamic y = new Y(); 

再次輸出:

w 
x 
w 

像現在編譯器會延遲採摘了任何方法,直到運行時,它會在運行時看到名爲x的變量實際上包含X類型的對象,然後選擇具有最佳擬合參數類型的方法。