Reputation: 924
I have a problem with generic class hierarchy and method override. I tried to do something like below:
public class Configuration<S> {
private List<S> elements;
<T extends Configuration<S>> Configuration<S> merge(T anotherConfig) {
return anotherConfig;
}
}
and the subclass looks like:
public class ExtendedConfiguration extends Configuration<String> {
@Override
ExtendedConfiguration merge(ExtendedConfiguration anotherConfig) {
return anotherConfig;
}
}
However, subclass does not compile and I have no clue how to declare method in Configuration class so I can override it in subclass with subclass type as parameter. I want to avoid explicit casting.
Upvotes: 1
Views: 869
Reputation: 1503
Due to Erasure: merge
in Configuration
becomes:
Configuration merge(Configuration anotherConfig) {
return anotherConfig;
}
For ExtendedConfiguration
to override merge
, it must have Configuration
as method param type. So, below ExtendedConfiguration
is fine:
class ExtendedConfiguration extends Configuration<String> {
@Override
Configuration<String> merge(Configuration anotherConfig) {
return anotherConfig;
}
}
@Override
instructs the compiler to check if the method is being inherited.
With the declaration in question:
public class ExtendedConfiguration extends Configuration<String> {
@Override
ExtendedConfiguration merge(ExtendedConfiguration anotherConfig) {
return anotherConfig;
}
}
it's overloading instead. If you remove @Override
, it will compile fine.
To achieve your requirement, you can use recursive generics:
The updated declarations may look like:
Configuration
class Configuration<T extends Configuration<T, S>, S> {
private List<S> elements;
Configuration<T, S> merge(T anotherConfig) {
return anotherConfig;
}
}
ExtendedConfiguration
class ExtendedConfiguration extends Configuration<ExtendedConfiguration, String> {
@Override
ExtendedConfiguration merge(ExtendedConfiguration anotherConfig) {
return anotherConfig;
}
}
Upvotes: 2