在浏览项目第三方库的某些来源时,我注意到以下代码模式:
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 { ... }
}
现实生活中的例子:
org.jdesktop.swingx.decorator.HighlightPredicate
(Source)org.pushingpixels.substance.api.renderers.SubstanceDefaultTableCellRenderer
(Source)拥有像这样的代码结构有什么好处?
我的第一个想法是“聚合”,但使用普通旧包可以实现同样的目的。那么什么时候/为什么使用公共内部类而不是包更好?
答案 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
的实例你需要的,即使两个类中定义的方法完全不同。
我从来不需要使用它,但真的很有趣。