【问题标题】:When to use inner classes in Java for helper classes何时在 Java 中将内部类用于辅助类
【发布时间】:2013-08-26 02:28:09
【问题描述】:

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

    public class Foo {
       private FooHelper helper;

       // constructor & any other logic

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

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

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

【问题讨论】:

  • 一般用于行动侦听器以及当您不想将呼叫暴露给其他人时。
  • @Vaibhav Jain 感谢您的链接,我知道语法,但我对何时使用它以及是否有任何权衡感到困惑
  • @SayemAhmed 我不确定这是否是唯一可用的选择,似乎可能有多种选择,并且作为新手我不确定正确的方法,所以仍在挖掘
  • @AnilSharma:想一想:“为什么要将thing 暴露给与thing 无关的外部世界”。我的意思是:如果您需要单个类所需的功能(类及其方法)而外部类不需要它或其功能,最好不要将此功能公开给其他类。这样可以避免污染外部世界,从而带来更好的架构。

标签: java inner-classes


【解决方案1】:

是的,让它成为一个内部类是非常有意义的。如果没有其他类需要它,请将其设为私有。如果它不需要对外部类的成员进行独占访问,请将其设为静态嵌套类,因为这样它需要更少的内存空间。

查看the official tutorial的推荐 -

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

【讨论】:

  • 什么时候应该是静态内部类?从功能上看有什么区别吗?
  • @Hild:static nested class 无权访问封闭类的成员(除非它是静态的)。如果这符合您的要求,请将其设为静态。另一方面,非静态内部类可以完全访问封闭类的成员。
  • @Hild 静态嵌套类不包含对其封闭类的合成引用。因此,除非您有特定的理由使其成为非静态的,否则请始终努力使其成为static nested classStatic inner class 在技术上是一个错误的术语。
  • 谢谢真的很有用,但是@eddieferetro 有一个合理的观点,为什么不使用私有方法来代替
  • 为什么静态嵌套类需要更少的内存空间?
【解决方案2】:

来自 JAVA SE 文档

为什么要使用嵌套类?

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

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

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        【解决方案5】:

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

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

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

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

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

        【讨论】:

        • 对不起,我是一个永远的新手,我想解释一下,因为我看不到内链在 OOP 世界中的位置:它们可以访问外部类的 private 成员。 . 你不能重复使用它们,只能通过复制粘贴...使代码丑陋,更难阅读和维护...(继续)
        • 我只理解您在优化应用程序时不公开大量公共方法的论点,但看不到它在 GUI 中的意义:侦听器模式为您提供了更改项目行为的选项(什么例如,在按钮“onclick”事件中执行)在执行时。如果监听器是一个内部类,它通常表明你真的不需要监听器功能:你想要一个永远不会重用的“onClick”方法(就像在 android 中通常发生的那样)
        • @eddieferetro 我能想到的一个用例是在特定类中使用时不公开整个对象。
        • @hild 但是,如果它是特定类的特定对象,为什么不在外部类中创建私有方法而不创建新的内部类?。
        • @eddieferetro 内部类只是一种干净地分离一些真正属于原始外部类的功能的方法。如果外部类中的某些功能在单独的类中实现,则它会最清晰。即使它在单独的类中,该功能也与外部类的工作方式密切相关。
        【解决方案6】:

        根据 Oracle Docs,简单解释

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

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

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

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

        【讨论】:

          【解决方案7】:

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

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

          【讨论】:

            【解决方案8】:

            Foo 的作用域是什么?当Foo 是具有自己生命周期的domain model classhelper 是公共服务时,似乎混合了两个具有非常不同范围/生命周期的对象。

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

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

            谁会为你创建Helper 的实例对我来说并不明显。

            【讨论】:

              【解决方案9】:

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

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

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

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

              【讨论】:

                【解决方案10】:

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

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

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2021-10-12
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-11-29
                  • 2019-03-05
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多