I have an abstract class containing an abstract method which returns a generic type. lets say
abstract class AbstractSample{
//class members
//this method needs to be overriden
public abstract SampleBuilder<? extends AbstractSample,?> copyBuilder ();
//other methods
//builder
public static abstract class SampleBuilder<T extends AbstractSample, B extends SampleBuilder<T,B>> {
//properties
private String as;
public SampleBuilder(AbstractSample object) {
this.as = object.as;
}
public B as(String as) {
this.as = as;
return (B)this;
}
public abstract T build();
}
}
Now I have a class Sample1 which extends this class and implements the method copyBuilder()
public class Sample1 extends AbstractSample {
//class members
@Override
public AbstractSample.SampleBuilder<Sample1,Sample1.Builder> copyBuilder() {
return new Sample1.Builder(this);
}
//other methods
//builder
public static class Builder extends SampleBuilder<Sample1,Builder> {
//implementation
//containing members and methods
}
}
There is another class Sample2 which is a subclass of Sample1. When I try to override the method copyBuilder() in this class, I am getting issues in the return type.
class Sample2 extends Sample1 {
//class members
// I am not allowed to implement this as below
@Override
public AbstractSample.SampleBuilder<Sample2,Sample2.Builder> copyBuilder() {
return new Sample2.Builder(this) ;
}
//other methods
//builder
public static class Builder extends SampleBuilder<Sample2,Builder> {
//implementation
//containing members and methods
}
}
IntelliJ says the method clashes with the one in the superclass , attempting to use incompatible return type.
Could anyone suggest how to implement the method copyBuilder() in Sample2 so that it returns Sample2.Builder .
I don't like a part B extends SampleBuilder<T, B>
. Why is it even useful to reference itself?
Anyway You can make it work if You change
SampleBuilder<Sample1,Sample1.Builder> copyBuilder()
to
SampleBuilder<? extends Sample1, ?> copyBuilder()
A complete example is below
public class Test {
abstract static class AbstractSample {
private String as;
//this method needs to be overriden
public abstract SampleBuilder<? extends AbstractSample, ?> copyBuilder();
public static abstract class SampleBuilder<T extends AbstractSample, B extends SampleBuilder<T, B>> {
private String as;
public SampleBuilder(AbstractSample object) {
this.as = object.as;
}
public B as(String as) {
this.as = as;
return (B) this;
}
public abstract T build();
}
}
static class Sample1 extends AbstractSample {
@Override
public SampleBuilder<? extends Sample1, ?> copyBuilder() {
return new Builder(this);
}
public static class Builder extends SampleBuilder<Sample1, Builder> {
public Builder(Sample1 sample1) {
super(sample1);
}
@Override
public Sample1 build() {
return null;
}
}
}
static class Sample2 extends Sample1 {
@Override
public SampleBuilder<? extends Sample2, ?> copyBuilder() {
return new Builder(this);
}
public static class Builder extends SampleBuilder<Sample2, Builder> {
public Builder(Sample2 sample2) {
super(sample2);
}
@Override
public Sample2 build() {
return null;
}
}
}
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments