2017-02-14 59 views
3

我有一個抽象類,它包含一個抽象方法,它返回一個泛型類型。 可以說如何覆蓋Java中的泛型返回類型的方法在多級別繼承的情況下

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(); 
    } 
} 

現在我有一個類的Sample1它擴展此類和實現方法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 
    } 
} 

還有一種類樣品2是樣本1的子類。 當我嘗試重寫此類中的方法copyBuilder()時,我遇到了返回類型中的問題。

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說方法與超類中的方法衝突,試圖使用不兼容的返回類型。

任何人都可以建議如何在Sample2中實現方法copyBuilder(),以便它返回Sample2.Builder。

+0

你可能有興趣在這個問題上它的工作關於通用返回類型es在Java中:http://stackoverflow.com/questions/36654841/java-compile-error-in-method-with-generic-return-type – jaco0646

回答

1

我不喜歡的部分B extends SampleBuilder<T, B>。爲什麼引用它自己甚至有用?

反正你可以做,如果你改變

SampleBuilder<Sample1,Sample1.Builder> copyBuilder()

SampleBuilder<? extends Sample1, ?> copyBuilder()

一個完整的例子如下

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; 
     } 
    } 
} 
} 
+0

是的這個作品! :)但是,如何? – bushra

+0

這意味着一個類是它自己的一個子類,當我從Sample1的一個對象調用copyBuilder()時,它返回Sample1.Builder,該類將被SampleBuilder <?擴展Sample1,?> ....這是否意味着Sample1擴展了Sample1? – bushra

+0

@bushra將'Sample1.Builder'改爲'''可以覆蓋'copyBuilder()'方法。你不能重寫一個方法並使返回類型不同或更一般。 –

2

這裏不需要泛型。這完美的作品:

abstract class AbstractSample { 

    public abstract SampleBuilder copyBuilder(); 

    public static abstract class SampleBuilder { 
     public abstract AbstractSample build(); 
    } 
} 

public class Sample1 extends AbstractSample { 

    @Override 
    public Sample1.Builder copyBuilder() { 
     return new Sample1.Builder(this); 
    } 

    public static class Builder extends SampleBuilder { 
     public Builder() { } 
     public Builder(Sample1 d) { } 

     @Override 
     public Sample1 build() { 
      return null; 
     } 
    } 
} 

class Sample2 extends Sample1 { 
    @Override 
    public Sample2.Builder copyBuilder() { 
     return new Sample2.Builder(this) ; 
    } 

    public static class Builder extends Sample1.Builder { 
     public Builder(Sample2 d) { } 

     @Override 
     public Sample2 build() { 
      return null; 
     } 
    } 
} 
+0

感謝您的答案。 – bushra

+0

但我確實需要泛型。讓我詳細介紹一下這個構建器的實現。 – bushra