Is there in java a way to write generic interface what points out to the implementor of such interface in more convenient way?
For example I've write interface:
public interface Updatable<T> {
void updateData(T t);
}
I want to point out that only instance of implementor can be passed in updateData(T t) method.
So, i have to write something like this:
public class Office implements Updatable<Office> {
@Override
public void updateData(Office office) {
//To change body of implemented methods use File | Settings | File Templates.
}
...
...
...
}
But seems it is a little ugly. Do you have better variants?
This is fine and is the least ugly way and clearest way to do it.
Generics is only there to ensure type safety, i.e. avoid casts. Your Updatable
interface is perfectly type-safe already. So why change anything?
I want to point out that only instance of implementor can be passed in updateData(T t) method.
The key question is: Why do you want to do that? I don't see any type-safety reason from looking at the interface itself why this is needed.
If the Office
class requires that the parameter to its updateData
method be Office
, fine. But that would be a requirement specific to the Office
class, and thus Office
should be responsible (and it is in your code) for implementing the interface with the appropriate type parameter.
People have been asking for the "This" type, mostly for fluent APIs. It's probably never gonna make it. But I think it's ok to just establish a convention - name the type variable This
to represent the type of this
. So readers see This
and know exactly what it is supposed to be; misuse is unlikely
public interface Updatable<This> {
void updateData(This t);
}
// any Foo implementing Updatable must supply This=Foo
public class Office implements Updatable<Office>
Since This
must be a subtype of Updatable<This>
, people often express that constraint
public interface Updatable<This extends Updatable<This>>
I think it is not necessary, and should not be done. The naming convention of This
is good enough.
That constraint is not strict enough either to prevent misuse. For example
public interface Foo<T extends Foo<T>>
public class Foo1 implements Foo<Foo1> // good, intended use
public class Foo2 implements Foo<Foo1> // compiles! but not intended
I would write
public interface Updatable<T extends Updatable<?>> {
void updateData(T t);
}
No less ugly, but more explicit that T
has to implement the interface.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With