【问题标题】:Constructor arguments in subclass子类中的构造函数参数
【发布时间】:2018-02-04 13:29:03
【问题描述】:

我有一个问题可能很简单,但我找不到出路。

这里是Parent 和Child 类,它们可以毫无问题地工作。

public class Parent {

    private A a;
    private B b;

    Parent (A a, B b){
        this.a = a;
        this.b = b;
    }

    public class A {}

    public class B {}

    private class C {}

    public class Child extends Parent {
        private final C c;

        Child(A a, B b, C c,) {
            super(a, b);
            this.c = c;
        }
    }
}

这就是问题所在:字段b 和c 是一些其他类ClassBC 的字段,而ClassBC 是类Child 的参数之一。即,

 public class Child extends Parent {
    private D d;
    Child(A a, C c) {
        // I must call super(...) here; but can't do that without `b`
        ClassBC classBC = new ClassBC(c);
        B b = classBC.getB();
        D d = classBC.getD();
    }
    // some methods
}

private class ClassBC{
    private D d;

    ClassBC(C c){
         // do something here to get 'B' and 'D'
    }
    public D getd(){
        return d;
    }

    public B getB(){
        return b;
    }
}

所以:

  • 我是傻了还是违反了一些规则?
  • 我尝试在Parent 类中使用Builder,这样它就可以在Child 类的构造函数中使用。正如预期的那样,它编译但失败了,因为Parent 类的字段在Child 类中不可用。
  • 我想避免在Child 类中使用构建器,因为它会导致存储库中的太多变化。我还能尝试什么?
  • 这是一个最小的示例,实际的类很复杂,有几个参数。

【问题讨论】:

  • super(a, new ClassBC(c).getB())?
  • ClassBC 中的b 来自哪里?
  • @JoeC 我不能这样做,让我编辑我的问题以澄清它。
  • 能否再添加一个构造函数:Parent (A a)?
  • 从技术上讲,我可以做到这一点,但如果没有'B',一些功能将无法工作。你会推荐使用Parent (A a),然后在Child的构造函数中,我做类似的事情:setB(b)。可能,这不是一个好主意,因为,我会暴露别人犯错误。

标签: java inheritance subclass superclass


【解决方案1】:

你不能用工厂方法来做。将 Child 构造函数设为私有,并添加静态方法 createChild 从该工厂方法创建子对象。 在调用 Child 构造函数之前创建 ClassBC 对象。

【讨论】:

  • 是的,这是一种方式,但会导致 500 多个地方发生变化。
  • @novice 好的,你可以给父级添加一个默认构造函数吗?并在您创建 Child 时调用它。在 super() 行通过之后。您可以使用 setter 将所需的对象设置为父对象。你的情况可以吗,如果你的对象是不可变的,我不知道。
  • 是的,我也这么认为(Mick Mnemonic 也提出了类似的建议;评论的问题)。但是,这是一个好习惯吗(只是问问)?
  • 我认为首先要做的事情应该是做一些有用的东西,好的做法是后来的。也许我想错了:)。这是一个很好的解决这个问题的方法。不过我会选择工厂方法
【解决方案2】:

我认为这应该适合你

public class Child extends Parent {

    private D d;

    private ClassBC bc;

    Child(A a, C c) {
        // Inline
        this(a, new ClassBC(c));
    }

    Child(A a, ClassBC bc) {
        super(a, bc.getB());
        this.bc = bc;
        this.d = bc.getD();
    }
}

【讨论】:

    猜你喜欢
    • 2021-03-12
    • 1970-01-01
    • 2013-10-25
    • 2021-07-05
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多