Possible to declare a method in super class that returns an object of type subclass?
-
03-06-2021 - |
Pregunta
I have a class called Calculator, which is extended by many other classes. It has a method called intern() which reads as follows:
public DailyValueCalculator intern() {
if (TimeSeriesIterator.containsMatchingCalculator(this)) {
TimeSeriesIterator.removeCalculator(this);
return TimeSeriesIterator.getMatchingCalculator(this);
} else {
return this;
}
}
If I have, say, a BetaCalculator called bc, I'd like to be able to intern it by saying
bc = bc.intern();
Currently though I have to say
bc = (BetaCalculator) bc.intern();
Is there any way to make it so that the intern() method would always have a return type of the type on which it was called? And if there isn't a way to do this, is there a reason why it's not possible?
Possible solutions I'm aware of though am unsatisfied with:
- Rewriting the intern() method in every calculator I write
Passing the intern() method a Class and having it return a T (e.g.
<T extends DailyValueCalculator> T intern(Class<T> returnType){...}
Giving DailyValueCalculator a Type <T> (i.e. making it DailyValueCalculator<T>) that all subclasses would be required to specify where T is equal to the type of the subclass and then having intern() return a T.
Solución
You can do it if you type your super-class with itself. Here is an example:
public abstract class SuperClass<S extends SuperClass<S>> {
public S intern() {
return (S) this;
}
public static class SubClass extends SuperClass<SubClass> {
private void methodOnlyInSubClass() {
System.out.println("subclass method");
}
public void myMethod() {
SubClass sub = intern();
sub.methodOnlyInSubClass();
}
}
}
Otros consejos
No there's no way to do this. Think about it: I know you know that the intern method is just going to return back the same class, but how could the compiler?