【问题标题】:how to override methods with generic return type in java in case of multi level inheritancejava - 在多级继承的情况下,如何在java中覆盖具有通用返回类型的方法
【发布时间】:2017-02-14 09:33:49
【问题描述】:

我有一个抽象类,其中包含一个返回泛型类型的抽象方法。 让我们说

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
  }
}

还有另一个类 Sample2,它是 Sample1 的子类。 当我尝试覆盖此类中的方法 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 。

【问题讨论】:

标签: java


【解决方案1】:

这里不需要泛型。这非常有效:

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

【讨论】:

  • 感谢您的回答。
  • 但我这里确实需要泛型。让我给出builder的详细实现。
【解决方案2】:

我不喜欢B extends SampleBuilder&lt;T, B&gt; 的角色。为什么引用自身甚至有用?

无论如何,只要你改变,你就可以让它工作

SampleBuilder&lt;Sample1,Sample1.Builder&gt; copyBuilder()

SampleBuilder&lt;? extends Sample1, ?&gt; 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;
        }
    }
}
}

【讨论】:

  • 这意味着一个类是它自己的子类,当我从 Sample1 的对象调用 copyBuilder() 时,它返回 Sample1.Builder ,它被类型转换为 SampleBuilder extends Sample1, ?> ....这是否意味着 Sample1 扩展了 Sample1?
  • @bushra 将Sample1.Builder 更改为? 使得copyBuilder() 方法可以覆盖。您不能重写方法并使返回类型不同或更通用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-08
  • 1970-01-01
  • 1970-01-01
  • 2016-01-24
  • 1970-01-01
  • 2015-09-12
  • 2013-10-25
相关资源
最近更新 更多