如何在实践中使用内部类

时间:2013-08-14 17:12:37

标签: java inner-classes anonymous-inner-class

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

一个例子也值得赞赏。

3 个答案:

答案 0 :(得分:11)

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

  1. 内部类可以看到外部类的字段(如果它不是静态的)。这意味着您不必处理外部类字段,就好像它们来自外部类。这意味着您的内部类需要外部类的实例才能工作。 如果你的类是静态的,那么它就像一个独立的类。
  2. 内部类与其拥有的类紧密相关。所以即使它是静态的,你知道它的名字与它所拥有的类有关。
  3. 说到这一点,你可以理解内部类必须在事物属于一起的地方使用。

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

    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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

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

您还应该检查收集API以查看其用法。