Reputation: 6484
I have an abstract java class that looks like:
public abstract class X {
public abstract void commonFunction();
}
I also have a bunch of maps, that I would like to be like this:
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 and E all extend X so they all implement commonFunction()
.
I'd like to be able to call a function like this:
someFunction(mapA); // or someFunction(mapB) etc.
...where someFunction looks like:
void someFunction(Map<String,X> mapX) {
...some stuff
x.commonFunction();
...more stuff
}
But the compiler complains with the things I've tried, which includes:
Map<String,X>
inside the someFunction
function call Also tried with an implemented interface instead of an extended class. Not sure what I'm doing wrong.
Edit:
I'm sorry, I rushed the question so I made a mistake. My maps are actually:
Map<String,List<A>> mapA = new HashMap<String,List<A>>();
...and so the someFunction
signature is actually:
void someFunction(Map<String,List<X>> mapX)
I'm not sure if that makes a big difference.
Upvotes: 1
Views: 82
Reputation: 10948
Try declaring
<T extends X> void someFunction(Map<String,List<T>> mapX)
Even A
being a subclass of X
, Map<String,List<A>>
is not a subclass of Map<String,List<X>>
.
You need to use a generic method as above to have a parameter that accepts any Map<String, List<any class that extends X>>
("any class that extends X
" is represented by the type parameter T
).
Upvotes: 2
Reputation: 19648
This should work:
<K extends X> void someFunction( Map<String, List<K>> mapX ) {
for ( List<K> list : mapX.values() ) {
for ( X obj : list ) {
obj.commonFunction();
}
}
}
Upvotes: 0
Reputation: 7804
But the compiler complains with the things I've tried
The rules of polymorphism does not apply to generics.
List<X> list = new ArrayList<A>; // Invalid. Polymorphism does not in declaration or referencing
However, this is valid:
List<X> list = new ArrayList<X>;
list.add(new A()); // Can add sub-type of X
list.add(new B());
Try this:
void someFunction(Map<String,? extends X> mapX) {
Upvotes: 1
Reputation: 18271
You can't call X
in your method, you must access it through the Map, like so
mapX.get("myKey").commonFunction();
Just tested it with this:
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");
}
}
Upvotes: 0