2014-09-30 68 views
1

我有一個抽象的Java類,看起來像:麻煩與Java繼承

public abstract class X { 
    public abstract void commonFunction(); 
} 

我也有一堆地圖,我想是這樣的:

Map<String,A> mapA = new HashMap<String,A>(); 
Map<String,B> mapB = new HashMap<String,B>(); 
Map<String,C> mapC = new HashMap<String,C>(); 
Map<String,D> mapD = new HashMap<String,D>(); 
Map<String,E> mapE = new HashMap<String,E>(); 

A, B,C,D和E都擴展了X,因此它們都實現了commonFunction()
我希望能夠調用這樣的功能:

someFunction(mapA); // or someFunction(mapB) etc. 

...其中someFunction樣子:

void someFunction(Map<String,X> mapX) { 
    ...some stuff 
    x.commonFunction(); 
    ...more stuff 
} 

但是編譯器我試過的事情抱怨,其中包括:

  • 通過用X代替[ABCDE]
  • 鑄造改變地圖聲明(左手側)映射成Map<String,X>裏面的someFunction函數調用

也嘗試用一個實現的接口,而不是一個擴展類。不知道我做錯了什麼。

編輯:
對不起,我衝的問題,所以我犯了一個錯誤。我的地圖實際上都是:

Map<String,List<A>> mapA = new HashMap<String,List<A>>(); 

...等someFunction簽名居然是:

void someFunction(Map<String,List<X>> mapX) 

我不知道是否是有很大的區別。

回答

2

嘗試宣告

<T extends X> void someFunction(Map<String,List<T>> mapX) 

即使A是的X一個子類, Map<String,List<A>>不是Map<String,List<X>>的子類。

您需要使用一個generic method如上爲具有接受任何Map<String, List<any class that extends X>>(由類型參數T表示「延伸X任何類」)的參數。

+0

是的,這沒有把戲。還有其他正確的答案,但解釋很好,你首先到達那裏! – RTF 2014-09-30 18:19:29

+0

如果我想將X改爲接口而不是類,是否有任何嚴重問題?編譯器似乎並不介意我是否保留所有內容,除非將X的定義更改爲接口,但如果將上面的代碼更改爲'',編譯器不會喜歡它。 – RTF 2014-11-09 15:41:32

1

但是,編譯與我試過

多態性的規則並不適用於仿製藥的事情抱怨。

List<X> list = new ArrayList<A>; // Invalid. Polymorphism does not in declaration or referencing 

然而,這是有效的:

List<X> list = new ArrayList<X>; 
list.add(new A()); // Can add sub-type of X 
list.add(new B()); 

試試這個:

void someFunction(Map<String,? extends X> mapX) { 
0

不能調用X在你的方法,你必須通過地圖訪問它,像這樣

mapX.get("myKey").commonFunction(); 

只是這個測試吧:

void tester() { 
    Map<String, X> testMap = new HashMap<String,X >(); 
    testMap.put("myKey", new A()); 
    someFunction(testMap); 
} 

void someFunction(Map<String, X> myMap) { 
    myMap.get("myKey").doSomething(); 
} 

abstract class X { 
    abstract void doSomething(); 
} 

class A extends X { 
    @Override 
    void doSomething() { 
     System.out.println("I'm A"); 
    } 
} 

class B extends X { 
    @Override 
    void doSomething() { 
     System.out.println("I'm B"); 
    } 
} 

class C extends X { 
    @Override 
    void doSomething() { 
     System.out.println("I'm C"); 
    } 
} 
0

這應該工作:

<K extends X> void someFunction(Map<String, List<K>> mapX) { 
    for (List<K> list : mapX.values()) { 
     for (X obj : list) { 
      obj.commonFunction(); 
     } 
    } 
}