2014-09-30 66 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(); 
     } 
    } 
}