Say I have an interface Interfacethat has a method aMethod() that should return itself, but also has a default implementation. Then I also have a class Foo that implements Interface and adds the additional method aFooMethod().
interface Interface {
public default Interface aMethod() {
// Some code
return this;
}
}
class Foo implements Interface {
public void aFooMethod() {
// Some code
}
}
Now I cannot call new Foo().aMethod().aFooMethod(); because aMethod() returns an Interface.
Now I could obviously go ahead and override the method in Foo:
class Foo implements Interface {
@Override
public Foo aMethod() {
Interface.super.aMethod();
return this;
}
public void aFooMethod() {
// Some code
}
}
The question I have is if there is a good way of forcing this, that a subclass has to return itself without it having to override that method?
My best aproach is to say something like this:
interface Interface<I extends Interface<I>> {
@SupressWarnings("unchecked")
public default I aMethod() {
// Some code
return (I)this;
}
}
But this is not what I would consider good as it has to use a SupressWarnings("unchecked"). Is there any better way?
I recently asked a question about this very same thing, but in C#. Both the problem and the answer are still the same though: Something like this isn't possible.
The pattern you mentioned
interface Interface<I extends Interface<I>> {}
seems like a good approach at first, but falls apart as soon as there is more than one class that implements Interface. And the problem is not the necessity to suppress a warning, it's actually something way bigger. If I create two classes like this:
class A implements Interface<A> {}
class B implements Interface<A> {}
it will still work. The constraint I extends Interface<I> only forces the type parameter I to be an Interface<I>, and A Does implement Interface<A>, so it satisfies the constraint even when Interface<A> is implemented by B.
I've been trying to find ways around this, but sadly, neither Java nor C# allow for anything along these lines.