gpt4 book ai didi

java - 在调用父类(super class)的构造函数之前,有什么方法可以在 Java 中初始化子类的成员变量?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:06:01 24 4
gpt4 key购买 nike

我需要这个,因为父类(super class)中的构造函数正在调用一个在子类中被覆盖的方法。该方法返回一个值,该值传递给子类的构造函数。但是父类(super class)构造函数必须在子类构造函数之前调用,所以我没有机会保存传入的值。

最佳答案

从父类(super class)构造函数调用重写的方法根本行不通 - 不要这样做父类(super class)构造函数必须始终在子类构造函数之前完成。当父类(super class)构造函数正在执行时,所讨论的对象是父类(super class)的(半初始化)实例,而不是子类!因此,如果您尝试从构造函数调用任何重写的函数,它可能依赖的子类字段尚未初始化(正如您所观察到的)。这是类设计的基本事实,没有解决方法。

Effective Java 2nd. Ed. 中所述(第 4 章,第 17 项):

There are [...] restrictions that a class must obey to allow inheritance. Constructors must not invoke overridable methods, directly or indirectly. If you violate this rule, program failure will result. The superclass constructor runs before the subclass constructor, so the overriding method in the subclass will get invoked before the subclass constructor has run. If the overriding method depends on any initialization performed by the subclass constructor, the method will not behave as expected.

如果可以更改父类(super class)实现,请尝试将对虚函数的调用移出构造函数。实现这一目标的一种方法是使用工厂方法:

class Super {
public void init() { ... }
}

class Subclass extends Super {
private Subclass() { super(); ... }
public void init() { super.init(); ... }
public static Subclass createInstance() {
Subclass instance = new Subclass();
instance.init();
return instance;
}
}

注意 Subclass 的构造函数是私有(private)的,以确保它只能通过 createInstance() 实例化,因此实例总是被正确初始化。 OTOH 这也阻止了进一步的子类化。但是,无论如何都不推荐对具体类进行子类化——要进行子类化的类应该是抽象的(在这种情况下使用 protected 构造函数)。当然,任何进一步的子类还必须具有非公共(public)构造函数和静态工厂方法,它们会勤奋地调用 init()...

关于java - 在调用父类(super class)的构造函数之前,有什么方法可以在 Java 中初始化子类的成员变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2529612/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com