java - 实际中如何使用内部类

标签 java inner-classes anonymous-inner-class

<分区>

为什么有人会使用内部类?使用 本地类子类 可以实现相同的功能。

也将不胜感激。

最佳答案

内部类可用于许多功能性情况。它们具有两个优势:

  1. 内部类可以看到外部类的字段(如果它不是静态的)。这意味着您不必像处理外部类的字段那样处理外部类字段。这意味着您的内部类需要外部类的一个实例才能工作。 如果您的类是静态的,那么它就像一个独立的类。
  2. 内部类与其所属类紧密相关。因此,即使它是静态的,您也可以通过它的名称知道它与其所属类相关。

说到这里,您就可以理解内部类必须用在事物属于一起的地方。

所以最有可能的情况是你不需要外部类之外的内部类。例如:

class ScreenCapture {
  class CaptureButtonListener implements ClickListener {
     public void onClick( ClickEvent click ) {
       //..capture
       pressCount++;
     }
  }

  Button button = new Button("capture");
  int pressCount = 0;

  void addListeners() {
    button.addClickListener( new CaptureButtonListener() );
  }
}

如你所见:

  • 您永远不需要 ScreenCapture 之外的 CaptureButtonListener。所以最好隐藏它(甚至将其声明为私有(private)或 protected )。
  • 内部类正在访问一个不属于它的字段:pressCount。这是可能的,因为它的实例绑定(bind)到 ScreenCapture 实例:您不能在静态方法中创建 new CaptureButtonListener():您必须在实例方法中使用它。

另一方面,静态内部类只是为了组织目的(也就是说两个类是相关的)。我将使用静态内部类改编前面的示例:

public class ScreenCapture {
  public static class CaptureButtonListener implements ClickListener {
    protected ScreenCapture controller;
    public CaptureButtonListener( ScreenCapture controller ) {
      this.controller = controller;
    }

     public void onClick( ClickEvent click ) {
       //..capture
       controller.pressCount++;
     }
  }

  Button button = new Button("capture");
  int pressCount = 0;

  public void captureRequested() {
    //do capture...
    pressCount++;
  }

  void addListeners() {
    button.addClickListener( new CaptureButtonListener(this) );
  }
}

请注意,在这种情况下:

  • 无法再从内部类访问变量 pressCount:您必须指定它所属的实例。
  • 您可以从外部实例化 CaptureButtonListener,但您可以直接从它的名称中看出:new ScreenCapture.CaptureButtonListener( screenCaptureInstance ) 它与 ScreenCapture 类相关(提高代码可读性)

现在您可能想知道为什么要创建一个无法访问其所有者字段的内部类?你是对的:在我们的例子中这不是很明智,因为你必须将 ScreenCapture 的实例传递给构造函数(因此你不能将它与 ScreenCapture 以外的任何其他类一起使用)。这只是为了证明差异。

下面的例子将给出前面的例子的全部意义:

您可以将您的监听器声明为 ScreenCapture 中的公共(public)静态接口(interface)

class ScreenCapture {
  public static interface class CaptureRequestListener {
     public void captureRequested( ClickEvent click );
  }
}

通过这种方式,您可以传递“如何处理捕获请求”的 ScreenCapture 实现

同样,接口(interface)的实现将知道它们正在实现特定于 ScreenCapture 的东西,因为它们将实现

public class MyImpl implements ScreenCapture.CaptureRequestListener {
  public void captureRequested( ClickEvent click ) {
    // I will count requests instead
  }
}

因此,您的代码比每个文件组织在单独的类中更清晰。

你也可以有一个处理基类(作为内部类的常见任务的抽象实现)

我希望一切都清楚 :-) 最好的祝福, 齐德

关于java - 实际中如何使用内部类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18238076/

相关文章:

Java : Inner class of an interface (from google guice)

java - 在 (*) 中可以访问多少个不同版本的 'x'?

java - 为什么从匿名内部类访问时要求局部变量是最终的?

java - 在 GAE blobstore java 中创建文件

java - 从嵌套内部类访问外部内部类

java - 为什么匿名类方法调用方法时aop无法执行?

java - javac生成的名称中的$$是什么意思?

java - 如何在Android上通过蓝牙发送字节数组?

java - Lagom 在启动时开始处理源代码

java - 我不明白这个递归程序