71

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

    public class Foo {
       private FooHelper helper;

       // constructor & any other logic

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

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

FooHelper在上述情况下,将其作为内部类有意义吗?如果这听起来很愚蠢,请道歉,但我对用例有点困惑。

4

10 回答 10

82

Yes, it makes perfect sense to make it an inner class. If no other classes need it, make it private. If it doesn't require exclusive access to the members of the outer class, make it a static nested class because then it will require less memory space.

Check out the recommendation from the official tutorial -

Use a non-static nested class (or inner class) if you require access to an enclosing instance's non-public fields and methods. Use a static nested class if you don't require this access.

于 2013-08-23T06:17:51.170 回答
19

来自 JAVA SE 文档

为什么使用嵌套类?

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

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

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

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

于 2016-12-17T18:08:52.360 回答
17

如果您认为这对于除 之外的其他类根本没有用FooHelper,那么将其作为 的内部类是有意义的。这种设计的一个例子可以在它定义一个私有内部类的地方找到Fooprivate FooHashMapKeySet

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

于 2013-08-23T06:21:01.730 回答
8

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

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

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

于 2013-08-23T06:28:37.767 回答
2

当内部类很小且不需要名称时,它们才有意义。GUI 中的侦听器是有意义的经典示例。

如果这个类又大又重要,它应该被命名并放在一个单独的文件中。

普通 GUI 示例中的侦听器类只做一件小事,通常只是分派给其他一些函数来完成实际工作。

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

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

于 2013-08-23T06:23:13.633 回答
2

根据 Oracle Docs,简单解释

使用嵌套类的令人信服的原因包括:

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

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

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

于 2019-07-01T17:16:24.113 回答
1

是的,使用内部类的好处是它可以访问外部类的成员。在您的情况下,如果您认为您FooHelper的任何其他类都不会使用,您可以将其设为内部类。

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

于 2013-08-23T06:23:41.180 回答
0

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

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

Java 中的类允许您拥有特定的功能,但有时您可能需要拥有单独的专门功能,但它也需要与您正在设计的类密切相关。

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

于 2013-08-23T06:29:57.907 回答
0

的范围是什么Foo?什么时候Foo模型类具有自己的生命周期并且helper是公共服务,似乎混合了两个具有非常不同的范围/生命周期的对象。

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

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

我不清楚谁会Helper为你做例子。

于 2013-08-23T06:26:08.180 回答
0

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

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

于 2015-03-10T19:40:38.143 回答