Reputation: 123
I have an abstract superclass ValueType
and two non-abstract subclasses IntType
and DoubleType
. How can define types in the superclass method like following
public abstract class ValueType {
public abstract <T extends ValueType> T add(T other);
}
that I allows to write concrete types (e.g. public IntType add(IntType other)
or DoubleType add(DoubleType other)
) in subclass method
public class IntType extends ValueType {
private int val;
public IntType(int val){
this.val = val;
}
public int getVal(){
return this.val;
}
@Override
public IntType add(IntType other) {
return new IntType(this.val + other.getVal());
}
public class DoubleType extends ValueType {
private double val;
public DoubleType(double val){
this.val = val;
}
public double getVal(){
return this.val;
}
@Override
public DoubleType add(DoubleType other) {
return new DoubleType(this.val + other.getVal());
}
In the above example, the subclass method does not override the superclass method.
Upvotes: 1
Views: 251
Reputation: 44398
Make the abstract class generic itself, not only its method.
Elevate the generic type <T extends ValueType>
as a class generic parameter. Note with this action the class ValueType
becomes also generic, therefore <T extends ValueType<T>>
takes the place to avoid raw types:
public abstract class ValueType<T extends ValueType<T>> {
public abstract T add(T other);
}
Then the concrete child class extends from a generic class and is forced to override the abstract method (private fields, getters and setters omitted):
public class IntType extends ValueType<IntType> {
@Override
public IntType add(IntType other) {
return new IntType(this.val + other.getVal());
}
}
public class DoubleType extends ValueType<DoubleType> {
@Override
public DoubleType add(DoubleType other) {
return new DoubleType(this.val + other.getVal());
}
}
By the way, you have two typos:
return new IntType(this.value + other.getVal());
should use this.val
.return new DoubleType(this.value + other.getVal());
should use this.val
as well.Upvotes: 1