Proper Use of "<T extends SuperClass>"
I am not familiar with Generics. Is this the correct use of " <T extends SuperClass>"? And do you agree that codes after using generics are better?
Before using Generics
=================================================
public abstract class SuperSample {
public void getSomething(boolean isProcessA) {
doProcessX();
if(isProcessA){
doProcessY(new SubASample());
}else{
doProcessY(new SubBSample());
}
}
protected abstract void doProcessX();
protected void doProcessY(SubASample subASample) {
// Nothing to do
}
protected void doProcessY(SubBSample subBSample) {
// Nothing to do
}
}
public class SubASample extends SuperSample {
@Override
protected void doProcessX() {
System.out.println("doProcessX in SubASample");
}
@Override
protected void doProcessY(SubASample subASample) {
System.out.println("doProcessY in SubASample");
}
}
public class Sample {
public static void main(String[] args) {
SubASample subASample = new SubASample();
subASample.getSomething(true);
}
}
After using Generics
=================================================
public abstract class SuperSample {
public void getSomething(boolean isProcessA) {
doProcessX();
if(isProcessA){
doProcessY(new SubASample());
}else{
doProcessY(new SubBSample());
}
}
protected abstract void doProcessX();
protected abstract <T extends SuperSample> void doProcessY(T subSample);
}
public class SubASample extends SuperSample {
@Override
protected void doProcessX() {
System.out.println("doProcessX in SubASample");
}
@Override
protected <T extends SuperSample> void doProcessY(T subSample) {
System.out.println("doProcessY in SubASample");
}
}
public class Sample {
public static void main(String[] args) {
SubASample subASample = new SubASample();
subASample.getSomething(true);
}
}
+3
2 answers
If you want to do what I think you want to do, I don’t think this is the right way (*). If you want a method that processes its own type to be implemented in each subclass, you can use the CRTP trick :
abstract class Super<S extends Super<S>> {
abstract void process(S s);
}
class SubA extends Super<SubA> {
void process(SubA s){ /* do something */ }
}
class SubB extends Super<SubB> {
void process(SubB s){ /* do something */ }
}
Note that this template provides a common signature for subclasses, for example. class SubA extends Super<SubB>will not compile.
Java itself uses this trick in java.lang.Enum, by the way.
(*) , , , .
+4