java - 指定情况下如何处理变量的初始化

标签 java swing oop refactoring initialization

我有一个类,其构造函数如下所示:

abstract class BasePanel extends JPanel {
  public BasePanel(A a) {
    // initializing fields from values passed to ctor
    this.a = a;
    // initializing gui components
    initializeComponents();
    setupPanels();
    concludeUiSetup();
  }

  // stuff
}

在构造函数中,首先要用传递给构造函数的值初始化的字段被初始化。然后依次调用 UI 设置所需的其他方法。对于特定于它们的 UI 设置,需要在子类中重写其中两个方法。

现在考虑一个扩展 BasePanel 的类 FooPanel。它的构造函数中需要更多的初始化参数。

class FooPanel extends BasePanel {
  public FooPanel(A a, B b) {
    super(a);
    this.b = b;
  }

  @Override
  public void initializeComponents() {
    super.initializeComponents();
    // I require b here, but oops, b is not initialized at this point, and so 
    // this will throw NPE.
    someTextField.setText(b.get());
  }

  // stuff
} 
此处的

initializeComponents 方法需要b,不幸的是此时尚未初始化。

什么是重组此代码的适当方法,以便:

  • 所需的字段在需要之前设置。
  • 使用 FooPanel(和其他面板)的代码并没有因为这一变化而变得困惑。

非常感谢任何帮助。谢谢。

最佳答案

您不应该从构造函数中调用可重写的方法。在这种情况下,您应该做的是定义一个仅初始化实例字段的构造函数,并将 GUI 的初始化放在一个可覆盖的 initialize() 方法中,该方法不会从构造函数中调用。

因此,要构建 FooPanel,您需要:

FooPanel p = new FooPanel(a, b);
p.initialize();

如果您不强制 FooPanel 的所有客户端都这样做,您可以将构造函数定义为私有(private),并提供一个工厂方法:

public static FooPanel create(A a, B b) {
    FooPanel p = new FooPanel(a, b);
    p.initialize();
    return p;
}

关于java - 指定情况下如何处理变量的初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10850037/

相关文章:

java - 如何在 main 中设置 Nimbus 外观

java - 防止 Enter 事件冒泡到主窗口

c++ - 用 C++ 编写方法/函数的四种相同方法?

c# - 本类(class)中使用的 OOP 概念

java - 如何使用 Graphics2D 围绕两个不同点旋转两个形状?

java - 多次递增计数器

java - 发送视频作为对用户的响应

java - 单元格渲染器和失去焦点

java - getView 不返回 View 参数

java - SpringBoot OAuth2 自定义异常响应