This is kind of difficult to explain, but I've looked everywhere, and I couldn't find any good answer.
I've also seen Stack Overflow questions How can I refer to the class type a interface is implementing in Java? and How do I return an instance of an object of the same type as the class passed in using Java 6?, but they couldn't answer my question. There is an exception when I apply inheritance.
There is an example, to make it easier to understand:
Let's say I have some interface called SelfMaker:
public interface SelfMaker <SELF>{
public SELF getSelf();
}
And A have a Dog, which can procreate with another dogs. So the dog is a "SelfMaker", like this:
public class Dog implements SelfMaker<Dog> {
String color;
public String toString() {
return "some " + color + " dog";
}
public Dog procreate(Dog anotherDog) {
Dog son = getSelf();
son.color = color;
return son;
}
@Override
public Dog getSelf() {
return new Dog();
}
}
But then, I have a DomesticDog, who is a Dog, but it has a lovely family who named him. Like this:
public class DomesticDog extends Dog {
private String name;
public String toString() {
return super.toString() + " named " + name;
}
}
Now, I have some class that handles couples of things that are "SelfMaker"s, let's call this class "Couple". Like this:
public class Couple<T extends SelfMaker<T>> {
private T first;
private T second;
public String toString() {
return first.toString() + " and " + second.toString();
}
}
THE EXCEPTION:
The exception comes when I want to create a couple of DomesticDog
s. Like this:
public class CoupleOfDomesticDogs extends Couple<DomesticDog>{
public DomesticDog procreate(){
DomesticDog son = first.procreate(second);
return son;
}
}
This will throw an exception on <DomesticDog>
complaining: Bound mismatch: The type DomesticDog is not a valid substitute for the bounded parameter <T extends SelfMaker<T>> of the type Couple<T>
I have already tried to change the generalised variable from class Couple to this: Couple<T extends SelfMaker<?>>
but the "son" won't be a DomesticDog (and I want the "son" to be a DomesticDog). If I add some cast, then it will compile, but it will be less legible.
So... here is the question: Is there a way to achieve this without castings and generalizations?