Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在超类';期间调用的重写方法中使用新添加的类构造函数参数;谁的构造函数?_Java_Inheritance_Inner Classes - Fatal编程技术网

Java 如何在超类';期间调用的重写方法中使用新添加的类构造函数参数;谁的构造函数?

Java 如何在超类';期间调用的重写方法中使用新添加的类构造函数参数;谁的构造函数?,java,inheritance,inner-classes,Java,Inheritance,Inner Classes,如果我有一个类Foo,它在其构造函数中调用类似someMethod的方法,并且我想重写someMethod,以利用我在这个子类中新添加的构造函数参数,我该如何做呢 让我们假设Foo有一个noargs构造函数,它调用someMethod。我希望我能做的事情是: public class Bar extends Foo { private String x; private String y; public Bar(String x, String y) {

如果我有一个类
Foo
,它在其构造函数中调用类似
someMethod
的方法,并且我想重写
someMethod
,以利用我在这个子类中新添加的构造函数参数,我该如何做呢

让我们假设
Foo
有一个noargs构造函数,它调用
someMethod
。我希望我能做的事情是:

public class Bar extends Foo {
    private String x;
    private String y;
    public Bar(String x, String y) {
        this.x = x;
        this.y = y;
        super();
    }
    @Override
    public void someMethod() {
        // do stuff with x and y
    }
}
当然,我不能这样做,因为Java坚持超类构造函数的调用在子类构造函数的第一行。如果我将它移动到第一行,那么它将在初始化x和y之前被调用,因此
someMethod
不会使用传递到构造函数中的值

看起来我可以通过使用内部类来解决这个问题,但是这太可怕了

public class Bar extends Foo {
    private String x;
    private String y;
    private Foo baz;
    public class Foobar extends Foo {
        @Override
        public void someMethod {
            // do stuff with Foo.this.x and Foo.this.y
        }
    }
    public Bar(String x, String y) {
        this.x = x;
        this.y = y;
        baz = new Foobar();
    }
    // override ALL of the remaining methods, including someMethod, delegating them to baz
}
这是一个可怕的解决方案,这是一个公认的模式,有没有更好的方法

注:为了澄清不明显的情况,类
Foo
不受开发人员的控制(例如,它是第三方库的一部分)。开发人员正试图扩展
Foo
,因此
Foo
做出的任何设计决策(例如,从构造函数调用的非最终方法)都不是开发人员可以影响的

编辑:人们在评论中询问
someMethod
是否为私有。它不是私人的,如果是这样的话,我就无法覆盖它。下面是所述类
Foo
的示例,以说明:

public class Foo {
    public Foo() {
        // some other stuff...
        someMethod();
    }
    public void someMethod() {
        // nothing of consequence
    }
    // some other methods, which aren't relevant to the question
}

你到底想解决什么问题?这看起来像是一个解决办法,可以更容易地实现。需要特别注意的是:在继承类的构造函数中调用非final方法时要小心,否则会出错。避免对尚未完全构造的类调用方法。“让我们假设Foo有一个noargs构造函数,它调用someMethod”@ModusTollens的想法是,类
Foo
是由其他人编写的,不受开发人员的控制。我们可能不同意他们的方法,但这不是我们可以影响的。这里的示例是Selenium
HtmlUnitDriver
。它有一个方法
modifyWebClient
,开发人员可以覆盖该方法来实现自定义行为。无可否认,javadoc根本没有明确说明在生命周期中何时调用该方法。但是从源代码中,我可以看到它是从一个私有方法
createWebClient
调用的,它本身是从构造函数调用的。好的,所以情况与问题中给出的有点不同。在其中,您写道“someMethod”在超级类控制器中被调用,并且在您的示例中被重写。调用私有方法的实际超类没有问题。您可能应该修改问题文本以反映实际代码。似乎您试图以Foo的作者不允许的方式修改类
Foo
对象的构造。坦率地说,这看起来像是黑客入侵。问题是你为什么需要这个,你想要达到什么目标?在我看来,对象创建和后续对象行为之间应该有明确的区别。而后者是一个调整的主体(这是继承概念的全部),前者是一种私人生活,一些语言,例如C++,显然是将父对象构造移出儿童的范围,这是为了好。