Reputation: 1940
Say I have this code -
public interface ParentInterface1 {
public List<? extends ChildInterface1> getChildren();
public void setChildren(List<? extends ChildInterface1> children);
}
public interface ParentInterface2 {
public List<? extends ChildInterface2> getChildren();
public void setChildren(List<? extends ChildInterface2> children);
}
public interface ChildInterface1 {
public String getField();
public void setField(String field);
}
public interface ChildInterface2 {
public String getField();
public void setField(String field);
}
public class LParentImpl implements ParentInterface1, ParentInterface2 {
private List<ChildImpl> list;
public List<ChildImpl> getChildren() {
return list;
}
public void setChildren(List<... wants to accept ChildImpl, which
implements ChildInterface1 & ChildInterface2> children) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
public class ChildImpl implements ChildInterface1, ChildInterface2 {
private String field;
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
}
Is there a way to make the setChildren() in the ParentImpl class work, without removing the Generic typing completely from the interfaces and implementation?
I'd like to do something like -
public void setChildren(List<? extends ChildInterface1 & ChildInterface2> children)
This sort of interface/implementation structure is valid for non Generic types, but it seems some aspect of the run-time erasure of Generics might make this impossible? Or am I missing some magic syntax?
Edit: Using the List<? extends ChildInterface1 & ChildInterface2> yields this compile error -
...\ParentImpl.java:20: > expected
public void setChildren(List<? extends ChildInterface1 & ChildInterface2> children) {
Upvotes: 4
Views: 4694
Reputation: 625057
You can do this:
public class MyClass<T extends ChildInterface1 & ChildInterface2> { ... }
Take a look at Java Generics Wildcarding With Multiple Classes
Upvotes: 4
Reputation: 21384
This isn't an answer, but I have to thank Jorn for his answer!
I stumbled upon this thread when trying to do exactly what your answer gave me (although it doesn't answer the original questioner). I tried to do this:
public static interface Displayable
extends Identifiable, Nameable { }
public void print(Displayable obj) {
System.out.println("[" + obj.getIdentity() + "] " + obj.getName());
}
which doesn't work because the object I am passing doesn't implement Displayable, but not Nameable and Identifiable individually.
Using Jorn's technique, I do this:
public <T extends Identifiable & Nameable> void print(T obj) {
System.out.println("[" + obj.getIdentity() + "] " + obj.getName());
}
and it works flawless!
I hope this will be helpful to others that having the similar problem as me (and stumbled to this thread).
Upvotes: 0
Reputation:
You can specify a method that takes an object that implements those two interfaces like this:
public <T extends IFirst & ISecond> void doSomething(T obj) {}
However, it won't matter much in your example, since both your child interfaces specify the same methods.
Upvotes: 11
Reputation: 147154
Your problem doesn't makes sense.
ParentInterface1.setChildren
accepts List<ChildInterface1>
. Therefore so much LParentImpl.setChildern
, but you are trying to constrain it so that it does not.
You might want to say, parameterise ParentInterface1
/2
, but I'd suggest avoiding multiple inheritance of interface wherever possible (not just where generics are involved).
Upvotes: 4