gpt4 book ai didi

Java - 在设置子字段之前在 super 实例化期间调用抽象方法的问题

转载 作者:行者123 更新时间:2023-12-01 13:37:19 25 4
gpt4 key购买 nike

这是我第一次使用这些论坛,所以我希望这个帖子是合适的并且我不会搞砸。这是 java - 我将尝试简化示例以专注于主要问题。任何帮助,将不胜感激!

假设我有两个类,家长 child ,其中 Parent 是一个抽象类,而 Child 扩展了 Parent。 (我正在即时编写此代码)...

public abstract class Parent {
// A bunch of fields that have been omitted...
public Parent() {
print(getX());
}

public abstract int getX();
}
public class Child extends Parent {
private int x;

public Child(int x) {
super();
this.x = x;
}

@Override
public int getX() {
return x;
}
}

我想实例化 Child,并在实例化后立即调用抽象方法。显然,目前存在一个问题,因为在 super() 的父级中调用 getX() 时尚未设置 x 字段,因此将始终返回 0。

但是,我希望在父级的所有子级的父级中完成此操作(如果将来有 Child2、Child3 等扩展父级)。即任何扩展 Parent 的东西都会打印出它们的“x”值。解决这个问题的方法是使用实​​例化的每个 Child 打印 getX() ,但由于某种原因,我似乎不得不在每个 Child 类中重复执行此操作,而不是在 Parent 中捕获它.

关于我应该如何处理这个问题(在实例化期间调用抽象方法)有什么建议吗?设计模式还是设计变更?使用 Child 中的重复调用?谢谢 :)

最佳答案

正如 akuzminykh 正确指出的那样,如果 x字段是从 Parent 派生的所有类的一部分,则该字段为 Parent field 。但是有时情况并非如此,然后您会希望在父级完全活着之前设置子字段。

这是实例化顺序中的一个常见问题,正如您所说的那样:

[...] there is an issue because the x field hasn't been set when getX() is called in the parent from super() [...]



因此,不能在父构造函数中进行这种调用。对此有一些常见的方法,大多数涉及某种 init()在实例完全构造后调用方法。

这样做的一种模式(不使用重量级依赖注入(inject))是工厂模式。见 https://www.tutorialspoint.com/design_pattern/factory_pattern.htm了解详细信息。

工厂模式的设计方式是,实例不仅由构造函数创建,而且最终由工厂返回,工厂给定用于实例化的值。那家工厂可以保证调用 init -方法,在实例完成后。

abstract class Parent {
// Notice the protected modifier!
protected Parent() {
// field initializations of Parent.
}

protected void init() {
// I replaced print with System.out.println here ot make it compile.
System.out.println(getX());
}

public abstract int getX();
}

abstract class ParentFactory<T extends Parent> {
public abstract T instance();
}

public class Child extends Parent {
private int x;

protected Child(int x) {
super();
this.x = x;
}

@Override
public int getX() {
return x;
}
}

class ChildFactory extends ParentFactory<Child> {

int x = 0;

public void setX(int x) {
this.x = x;
}

@Override
public Child instance() {
Child instance = new Child(x);
instance.init();
return instance;
}
}

@Test
public void test() {
ChildFactory factory = new ChildFactory();
factory.setX(7);
Child child = factory.instance();
System.out.println("And child has x: " + child.x);
}

请注意,这种工厂(有状态工厂)与 Builder 模式中的 Builder 非常相似。它的不同之处仅在于它通常被重复使用,而不是当场创建。您可以改变这种模式,因为 ChildFactory 中还有一个显式方法。它在 ChildFactory 的状态字段上采用显式参数:

public Child instance(int x) {
Child instance = new Child(x);
instance.init();
return instance;
}

关于Java - 在设置子字段之前在 super 实例化期间调用抽象方法的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61998204/

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