Java 什么';拥有接口/类的公共静态内部类的优点是什么?
在浏览我的项目的第三方库的一些源代码时,我注意到以下代码模式:Java 什么';拥有接口/类的公共静态内部类的优点是什么?,java,Java,在浏览我的项目的第三方库的一些源代码时,我注意到以下代码模式: public interface MyInterface { public static class MyClass1 implements MyInterface { ... } public static class MyClass2 implements MyInterface { ... } public static class MyClass3 implements MyInterface { .
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.HighlightPredicate
- Substance:
()org.pushingpixels.Substance.api.renderers.SubstanceDefaultTableCellRenderer
我的第一个想法是“聚合”,但使用普通的旧包也可以实现同样的效果。那么什么时候/为什么使用公共内部类而不是包更好呢?我认为这是由聚合引起的,也许它们也不值得创建顶级类。我有时会这样做,如果有些东西太小,无法创建一个包(将它们与其他包分开),但是相应的类应该只在顶级类的上下文中使用。在我看来,这是一个设计决策 decorator模式可能是一个很好的例子,它们可以应用于顶级类,但可能太简单了,不值得也应用于顶级类。通过将它们用作内部类,可以轻松地显示所有权 乍一看,这在软件包中并不明显。您可以直接看到依赖类/接口
此外,还可以访问类的私有字段,这可能很有用,并且比包私有范围更细粒度 我能想到的一个用途是提供接口的现成实现,任何人都可以公开使用,但在概念上仍然绑定到母接口
只有当接口很简单(因此内部实现类很小),没有太多,并且大多数接口客户机实际上需要它们时,这才有意义。否则,它们会使源文件变得混乱,使其更难理解。内部接口必须是静态的才能被访问。接口不与类的实例相关联,而是与类本身相关联,因此可以使用
Foo.Bar
,就像这样。就类及其内部类而言(不适用于接口)。一个区别是内部类可能使用外部类的私有成员,如果他们是“兄弟”(独立的顶级类),情况就不是这样了
例如:
public class MyBaseClass {
private static String staticField = "outer";
public static class MyClass1 extends MyBaseClass {
public MyClass1() {
MyBaseClass.staticField = "inner1";
}
}
}
如果您将
MyClass
移出外部类,这将不起作用。我认为公共静态内部类的原因是“基本”类的附加工具或实用程序。多年前,当我问我的老师这方面的问题时,他回答说,通过这种方式,您可以为同一对象公开一个完全不同的接口。假设你有
public class MyBaseClass {
public static class MyClass1 {
public int myClassMethod1() {...}
public int myClassMethod2() {...}
}
...
public void myBaseMethod1() {...}
public void myBaseMethod2() {...}
}
由于MyClass1
的实例可以访问MyBaseClass
的内部,因此您可以根据需要公开与MyClass1
实例或MyBaseClass
实例相同的内部行为,即使两个类中定义的方法完全不同
我从来都不需要使用它,但它真的很有趣。这样做可以为您节省一些额外的源代码文件,并可以为类提供一个很好的层次名称,即
org.foo.bar.XY.Default
而不是org.foo.bar.DefaultXY我没有查看您发布的实际示例,但是一个区别是,内部类可能使用外部类的私有成员,如果它们是“兄弟”(独立的顶级类),则情况并非如此。顺便说一句:内部类对于接口默认是静态的,您不能为接口使用非静态嵌套类。@Peter:但是关键字static
是可选的。对于一个接口来说,所有内部类都是静态的。@John,没错,public
也一样当children类本身没有意义时,可以这样建模父子关系。例如Map.Entry;如果条目本身与某种地图无关,则不会有条目,因此它们不应该是顶级类。