2009-12-02 60 views
2

重載的方法更具體的數據類型我有一些數組列表具有相同接口的類型的不同對象,例如:使用在Java中

Interface interface {} 

class A implements interface {} 

class B implements interface {} 

我也有一個重載的方法實現該接口的所有那些繼承的對象:

public void doSomething(A obj) {} 

public void doSomething(B obj) {} 

編譯器還強迫我寫一個重載的方法與接口:

public void doSomething(interface obj) {} 

然後我去通過列表的值並調用方法:

for (interface obj: myList) { 
    doSomething(obj); 
} 

現在,因爲obj的類型是「接口」,在DoSomething的(接口OBJ)是調用,而不是說DoSomething的(B OBJ)如果OBJ實際上類型B.

我可以用java做,否則的,所以它調用DoSomething的(A OBJ)當obj是A型和DoSomething的(B OBJ)當obj是B型的?

+0

在什麼類的doSomething()方法實現?他們是A,B還是其他一類的成員。 – 2009-12-02 19:48:59

+0

它們是在爲A和B創建適配器/包裝器對象的工廠類中實現的。 – arsenbonbon 2009-12-02 22:16:39

回答

3

Java使用早期綁定,這意味着obj的類型編譯時定義,而不是在運行時。由於你的代碼表明obj是類型接口,因此編譯器將始終調用將接口作爲參數的方法。

你有兩個選擇,使其調用正確的方法:

  1. (非常難看)檢查使用的instanceof obj類型及演員,同時調用對象。

    for (interface obj: myList) { 
        if(obj instanceof A) 
         doSomething((A) obj); 
        else if(obj instanceof B) 
         doSomething((B) obj); 
        else 
         doSomething(obj); // Calls the method receiving Interface 
    } 
    
  2. 實現接口訪問者的方法,所以訪問當A和B都將調用方法的doSomething(本)。

    interface Interface { 
        void visit(OtherClass methodHolder); 
    } 
    
    class A implements Interface { 
        public void visit(OtherClass methodHolder) { 
         methodHolder.doSomething(this); 
        } 
    } 
    
    class B implements Interface { 
        public void visit(OtherClass methodHolder) { 
         methodHolder.doSomething(this); 
        } 
    } 
    
+0

訪問者+1 – Bozho 2009-12-02 20:07:09

-1

您可以使用Java instanceof運營商檢查什麼類實現的接口:

if(obj instanceof A) { 
    // do something 
} else { 
    // do something else 
} 

但更好的方法是有隻會採取任何對象,它是你有接口的實例的方法正如Atmocreations所提到的那樣。

0

這裏的多態的方法是在你的interface定義doSomthing()AB實現它,那麼你的循環中調用它。根據具體的對象,將運行不同的代碼。

2

有一個竅門。免責聲明:這是醜陋的。

如果與DoSomething的方法,你的類被稱爲類表演,如:

class Performer { 
    void doSomething(A x); 
    void doSomething(B x); 
    void doSomething(Inf x); 
} 

你可以添加到您的接口IFC:

interface Ifc { 
    void acceptPerformer(Performer p); 
} 

在這兩個類A和B實現它像這樣的:

void acceptPerformer(Performer p) { 
    p.doSomething(this); 
} 

和實現DoSomething的(IFC x)的方法是這樣的:

void doSomething(Ifc x) { 
    x.acceptPerformer(this); 
} 

這聽起來很奇怪,但它的工作原理。當調用接受接口的doSomething方法時,它將調用具體類上的acceptPerformer。當該課程重新調用doSomething時,它會知道它是哪種類型,並將調用正確的doSomething!

+0

您基本上描述訪問者模式。 – Robin 2009-12-02 20:06:24

+0

並且模式從不醜陋;) – Bozho 2009-12-02 20:08:31

+0

如果原始海報想要進一步閱讀,這稱爲「雙派遣」,並且很少在Java中使用(在我的經驗中),其中運行時類型信息容易可用並且投射是正常活動。如有必要,仍然是一個有用的習慣用語。 – PSpeed 2009-12-02 20:09:38

0

被定義爲接口的一部分的方法

public void doSomething(interface obj) 

?如果編譯器迫使你編寫該方法,那麼這是唯一有意義的。

然後,這引出了你爲什麼試圖在你的實現中改變接口的方法簽名的問題。該接口旨在成爲該對象看起來像什麼的合同。

+0

不,我在這裏混淆了一些東西,抱歉,編譯器沒有說什麼,這是一個運行時錯誤。該方法不是界面的一部分。 – arsenbonbon 2009-12-02 22:12:56