6

为什么有人会使用inner class? local class使用或可以实现相同的功能subclass

一个例子也将不胜感激。

4

3 回答 3

11

内部类可用于许多功能案例。它们具有两个优点:

  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。所以最好隐藏它(甚至将其声明为私有或受保护)。
  • 内部类正在访问一个不属于它的字段:pressCount。这是可能的,因为它的实例与 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 内的公共静态接口

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

这样,您可以通过“如何处理捕获请求”的 ScreenCapture 实现

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

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

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

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

我希望一切都清楚:-) 最好的问候,Zied

于 2013-08-14T17:43:08.103 回答
1

内部类的作用域是声明它们的类,因此根据您的作用域,您将决定创建一个内部类。是的,如果您的范围是方法的本地,您可以创建本地类,因此做出决定是由范围驱动的。

我建议阅读以下内容以获得更多理解和知识URL

于 2013-08-14T17:38:01.753 回答
1

内部类可以用来实现多重继承。所以如果你的类已经扩展了一个类,你可以通过内部类扩展更多的类。

您还应该检查集合 API 以查看其使用情况。

于 2013-08-14T17:44:23.027 回答