2011-03-22 39 views
35

,同时通过我的项目的第三方库的一些消息来源浏览我注意到下面的代码模式:有一个接口/类的公共静态内部类的优点是什么?

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

有这样的代码结构的优点是什么?

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

+0

我没看你已经张贴了现实生活中的例子,但一个区别是内部类可能使用外部类的私有成员,如果他们是“兄弟姐妹”(单独的顶级类) – 2011-03-22 12:05:37

+0

好问题,则不是这种情况。就我个人而言,我建议避免这种模式,因为它将公共课程隐藏在人们通常不期望找到它们的位置,而没有为折衷提供任何明显的益处。但也许有人知道这种模式的好处应该是什么。 – aroth 2011-03-22 12:06:29

+0

@Grzegorz,接口不能有私人成员。 – 2011-03-22 12:09:51

回答

17

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

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

对于软件包来说,这一看起来并不明显。您直接看到依赖类/接口。

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

10

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

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

1

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

4

就类和它们的内部类而言,(不适用于接口)的一个区别是内部类可能使用外部类的私有成员,如果它们是“兄弟” '(单独的顶级课程)。

例子:

public class MyBaseClass { 

    private static String staticField = "outer"; 

    public static class MyClass1 extends MyBaseClass { 

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

    } 
} 

,如果你移动的MyClass了外部类的这是行不通的。

0

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

0

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

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

由于MyClass1实例访问的MyBaseClass的内部,你可以公开相同的内部行为的MyClass1实例或为MyBaseClass实例作为你需要,即使这些方法定义在两个班都完全不同。

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

1

这样做,这样可以节省你一些额外的源代码文件,并能够为该类一个很好的层次名称,而不是即org.foo.bar.XY.Defaultorg.foo.bar.DefaultXY

相关问题