Reputation: 1515
I'm wondering if there's a better way to do this. What I want is to have a concrete method in an abstract class return the concrete instance that extends the abstract class.
Here's what I'm doing now:
abstract class ParentClass<T extends ParentClass> extends RelativeLayout {
...
public T aMethod(){
return (T)this;
}
}
and
class ChildClass1 extends ParentClass<ChildClass1>{
...
}
I don't think I should have to cast this to T since this always is an instance of T.
Upvotes: 1
Views: 1321
Reputation: 43671
The problem is that there is no way to reference the type of "this very class". This is why you have to use constructs like abstract class Base<T extends Base<T>>
. But as many mentioned in comments, nothing prohibits you from defining Subclass1 extends <Subclass2>
. There is just now syntactic way to guarantee that T
is "this very class".
You can, however, enforce this guarantee in the runtime. You can use something like TypeTools or other methods to extract used generic type and the make sure that current instance has this type. This would probably result in something like:
public abstract class Base<T extends Base<T>> {
protected Base() {
final Class<?> t = (Class<?>) ((ParameterizedType) getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
if (!t.isInstance(this)) {
throw new IllegalArgumentException();
}
}
public T getInstance() {
@SuppressWarnings("unchecked")
T thisIsT = (T) this;
return thisIsT;
}
}
This class can be instantiated:
public class Extension1 extends Base<Extension1> {}
But this one not:
public class Extension2 extends Base<Extension1> {}
The Base
constructor guarantees that this
is instance of T
therefore the cast of this
to T
is safe.
Upvotes: 1