何时在Java中使用辅助类的内部类

问题描述 投票:48回答:10

如果我有一个类和一个辅助类来执行它的一些功能,那么将它作为内部类是否有意义。

    public class Foo {
       private FooHelper helper;

       // constructor & any other logic

       public void doSomeThing() {
         helper.do();
       }
    }

    public class FooHelper {
        public void do() {
         // code
        }
    }

在上述情况下,将FooHelper作为一个内部类是否有意义?道歉,如果这听起来很愚蠢,但我对用例感到困惑。

java inner-classes
10个回答
55
投票

是的,让它成为内在阶层是完全合理的。如果没有其他类需要它,请将其设为私有。如果它不需要对外部类成员的独占访问,则将其设置为静态嵌套类,因为这样会占用更少的内存空间。

查看the official tutorial的推荐 -

如果需要访问封闭实例的非公共字段和方法,请使用非静态嵌套类(或内部类)。如果不需要此访问权限,请使用静态嵌套类。


0
投票

什么时候使用内部类?

  1. 内部类不需要任何附加或单独的文件。
  2. 内部类比较小并且与“父”类或“外部”类紧密耦合。避免许多帮助类,并适合解释OOD遏制原则。
  3. 同一文件中的所有代码都提高了可读性并提高了性能(如在线代码)。它们的重要性在编码中越来越重要,并被视为一种良好的做法。
  4. 当您想要动态定义回调时,匿名内部类非常有用。
  5. 内部类的对象可以访问创建它的对象的实现 - 包含私有数据。
  6. 内部类能够访问其父类的行为,包括私有。

0
投票

根据Oracle Docs,简单解释

使用嵌套类的令人信服的理由包括:

它是一种逻辑分组仅在一个地方使用的类的方法:如果一个类只对另一个类有用,那么将它嵌入该类并将两者保持在一起是合乎逻辑的。嵌套这样的“帮助类”使得它们的包更加简化。

它增加了封装:考虑两个顶级类A和B,其中B需要访问A的成员,否则这些成员将被声明为私有。通过将类B隐藏在类A中,可以将A的成员声明为私有,并且B可以访问它们。另外,B本身可以隐藏在外面。

它可以带来更易读和可维护的代码:在顶级类中嵌套小类会使代码更接近于使用它的位置。


14
投票

如果你认为FooHelper根本不会对Foo以外的其他类有用,那么将它作为private Foo的内部类是有意义的。这种设计的一个例子可以在HashMap中找到,它定义了一个私人内部类KeySet

否则将它作为private实例看起来不错。


12
投票

来自JAVA SE Docs

为什么使用嵌套类?

它是一种逻辑分组仅在一个地方使用的类的方法:如果一个类只对另一个类有用,那么将它嵌入该类并将两者保持在一起是合乎逻辑的。嵌套这样的“帮助类”使得它们的包更加简化。

它增加了封装:考虑两个顶级类A和B,其中B需要访问A的成员,否则这些成员将被声明为私有。通过将类B隐藏在类A中,可以将A的成员声明为私有,并且B可以访问它们。另外,B本身可以隐藏在外面。

是的,使用FooHelper作为内部类是有意义的。


6
投票

以下是内部类的一些用法。

  • 内部类用于获取可以比方法更好地获取对象的功能。
  • 它们可以在需要一组多个操作并且类内部可重用性很好的情况下使用,并且不会访问它们,而是外部类之外的方法。
  • 内部类也是为了实现多重继承。
  • 内部类在类上下文中有用时使用。
  • 它们用于分隔类内的逻辑。

因此,如果您有一些匹配上述点的要求,则可以使用内部类。最好使内部类private阻止来自其他类的访问。在您的情况下,使用内部类有助于使代码可读并在外部类中分离逻辑。


1
投票

当内部类很小并且不需要名字时,内部类是有意义的。 GUI中的监听器是有意义的经典示例。

如果类很重要,则应将其命名并放在单独的文件中。

普通GUI示例中的监听器类做了一件小事,通常只是调度到其他一些函数来做实际工作。

我还经常使用静态嵌套类(技术上不是内部类)用于仅在另一个类的上下文中使用的类 - Map.Entry就是一个很好的例子。它只与Map一起使用,因此将Entry的定义作为Map接口的一部分会使组织有意义。

我通常没有太多用于其他类型的嵌套类,如非静态成员类和本地类。但他们偶尔会有用。有关合法使用成员类的一个很好的示例,请参阅LinkedList.ListItr的源代码。这是一个私有内部类,其目的是为ListIterator提供LinkedList的实现。为此,访问LinkedList中的私有数据非常有用。要仅使用顶级类来实现此目的,必须在LinkedList中公开更多公共方法,以允许ListIterator获取LinkedList的底层实现。相反,使用内部类允许LinkedList将其实现保持为私有,就像它应该的那样。


1
投票

是的,使用内部类的优点是它可以访问外部类的成员。在你的情况下,如果你认为你的FooHelper不被任何其他类使用,你可以使它成为内部类。

要查看内部类的实用程序,请查看AWT的示例。匿名内部类广泛用于事件处理程序。


0
投票

什么是Foo的范围?当Foodomain model class与它自己的生命周期和helper是常见的服务,似乎混合两个具有非常不同的范围/生命周期的对象。

通常,域实体拥有自己的生命周期,从创建,持久性到GC。另一方面,帮助者或服务是静态的或更好的动态,生命周期等于整个应用程序,例如春豆。

一旦您的域实体包含服务的引用,它就会给您带来严重的问题。例如。每次调用存储库的Get都需要将此服务的引用注入域实体。我建议避免这种模式。

我不清楚谁会为你制作Helper的例子。


0
投票

Hild,是的,在很多情况下使用内部类是有意义的。

可以这样想 - 内部类将与外部类一起生存和死亡,因此外部类特别需要的任何功能都可以添加到内部类中。流行的例子是 - 大多数情况下的监听器 - KeyListeners的类型,MouseListeners,eventListeners。

Java中的类允许您具有特定的功能,但有时您可能需要具有单独的专用功能,但它还需要与您正在设计的类紧密相关。

可以有四种类型的内部类。一个简单的谷歌搜索可以帮助您找到更多相关信息。


0
投票

嵌套类使您能够对仅在一个地方使用的类进行逻辑分组,增加封装的使用,并创建更易读和可维护的代码。本地课程,匿名课程。

http://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html

© www.soinside.com 2019 - 2024. All rights reserved.