具有接口/类的公共静态内部类的优点是什么?

时间:2011-03-22 12:01:18

标签: java

在浏览项目第三方库的某些来源时,我注意到以下代码模式:

public interface MyInterface {
    public static class MyClass1 implements MyInterface { ... }
    public static class MyClass2 implements MyInterface { ... }
    public static class MyClass3 implements MyInterface { ... }
}

或者这个:

public class MyBaseClass {
    public static class MyClass1 extends MyBaseClass { ... }
    public static class MyClass2 extends MyBaseClass { ... }
    public static class MyClass3 extends MyBaseClass { ... }
}

现实生活中的例子:

  • SwingX:org.jdesktop.swingx.decorator.HighlightPredicateSource
  • 物质:org.pushingpixels.substance.api.renderers.SubstanceDefaultTableCellRendererSource

拥有像这样的代码结构有什么好处?

我的第一个想法是“聚合”,但使用普通旧包可以实现同样的目的。那么什么时候/为什么使用公共内部类而不是包更好?

7 个答案:

答案 0 :(得分:17)

我认为这是由聚合推理的,也许他们也不值得创建顶级课程。我有时会这样做,如果有一些东西要小到创建一个包(将它们与其他包分开),但相应的类应该只在顶级类的上下文中使用。在我看来,这是一个设计决定。

装饰器模式可能是一个很好的例子,它们可以应用于顶级类,但可能很简单,它们也不值得它们也是顶级的。您可以通过将它们用作内部类来轻松显示所有权。

乍一看包装时并不是那么明显。您可以直接看到依赖类/接口。

此外,可以访问类的私有字段,这可能很有用,并且比包私有范围更精细。

答案 1 :(得分:10)

我能想到的一个用途是提供现成的界面实现,可供任何人公开使用,但仍然在概念上与母界面相关联。

只有当接口很简单时才有意义(因此内部实现类很小),它们没有太多,并且大多数接口客户端实际上都需要它们。否则他们会混淆源文件,使其更难理解。

答案 2 :(得分:4)

就类及其内部类而言(不适用于接口)一个区别是内部类可能使用外部类的私有成员,如果不是这样的话他们是'兄弟姐妹'(单独的顶级课程)。

示例:

public class MyBaseClass {

    private static String staticField = "outer";

    public static class MyClass1 extends MyBaseClass { 

      public MyClass1() {
          MyBaseClass.staticField = "inner1";
      }

    }
}

如果您将MyClass移出外部类,则无效。

答案 3 :(得分:1)

内部接口必须是静态的才能被访问。接口不与类的实例相关联,但与类本身相关联,因此可以使用Foo.Bar访问它,就像这样。

答案 4 :(得分:1)

这样做可以节省一些额外的源代码文件,并且可以为类提供一个很好的层次结构名称,即org.foo.bar.XY.Default而不是org.foo.bar.DefaultXY

答案 5 :(得分:0)

我认为公共静态内部类的原因是“基础”类的附加工具或实用程序。

答案 6 :(得分:0)

多年前,当我向老师询问这个问题时,他回答说,通过这种方式,您可以为同一个对象公开一个完全不同的界面。假设你有

public class MyBaseClass {
    public static class MyClass1 {
       public int myClassMethod1() {...}
       public int myClassMethod2() {...}
    }
    ...
    public void myBaseMethod1() {...}
    public void myBaseMethod2() {...}
}

由于MyClass1的实例可以访问MyBaseClass的内部,因此您可以公开与MyClass1的实例相同的内部行为或MyBaseClass的实例你需要的,即使两个类中定义的方法完全不同。

我从来不需要使用它,但真的很有趣。