【问题标题】:Interface inside class类内接口
【发布时间】:2016-04-10 12:58:43
【问题描述】:

类内、嵌套类和类外使用接口有什么区别。

当我在 Oracle 阅读 Questions and Exercises: Nested Classes 中的 DataStructure.java 课程时(在此处粘贴示例片段):

public class DataStructure {
//some code
    interface DataStructureIterator extends java.util.Iterator<Integer> { } 

    // Inner class implements the DataStructureIterator interface,
    // which extends the Iterator<Integer> interface

    private class EvenIterator implements DataStructureIterator {
//rest code
  1. 所以代码显示界面中没有任何主体。我不能只用java.util.Iterator&lt;Integer&gt; 扩展 EvenIterator 类而不是创建这个接口并实现它吗?

  2. 在类外部/内部声明干扰之间是否还有其他区别(除了代码可读性)?

  3. 当外部类被接口扩展时会发生什么。它会对嵌套类产生任何影响吗?

只是想确定这些东西以了解如何正确使用它们,感谢您的宝贵时间。

【问题讨论】:

  • 没有区别,interface 总是隐含的static,即使没有这样声明。在这种情况下,接口被用作穷人的类型别名。
  • 通常你只为对父类有一些功能依赖的东西创建内部类。比如你有一个可点击的View,那么你就有一个名为View.OnClickListener的内部类监听器,否则首选外部类
  • @cricket_007,事实上,即使在这种情况下,最好使用单独的接口,因为有一天有人可能希望创建一个替代的View 实现。或者也许在其他可点击对象中重用这个接口。请注意,Java 很少(如果有的话)在标准库中使用嵌套接口。
  • @SergeyTachenov java.util.Map.Entry 是我提到的情况的示例嵌套接口
  • @cricket_007,是的,这是一个很好的例子。我更多地考虑各种听众(例如,ActionListener 不是Action 的一部分)。不过,拥有一个单独的MapEntry 接口一点也不会有什么坏处。

标签: java class interface


【解决方案1】:
  1. 所以关于代码显示接口中没有任何主体。我不能只是扩展 EvenIterator 类 java.util.Iterator 而不是创建这个接口和 实现了吗?

是的,你可以。但这种方式可能更具可读性和可扩展性。即使现在没有成员,以后也可能会添加。

  1. 在课堂内外声明干扰之间是否还有其他区别(除了代码可读性)?

嵌套接口是隐式静态的,因此唯一的影响是嵌套接口是封闭类命名空间的一部分。

因为类的成员可以声明为protectedprivate,这也适用于嵌套接口。但是,使用private 接口几乎没有意义,因为它们只能在同一个类中实现,那么为什么要首先使用接口呢?但是,protected 接口可能很有用。例如,您可能有一个抽象工厂方法,子类使用该方法为父类提供实例。这是一个人为的例子:

public abstract class Enclosing {

    protected interface JobHandler {
        void handle(Job job) throws JobException;
    }

    protected abstract JobHandler createJobHandler();

    // public methods omitted

    private void doTheJob(Job job) {
        createJobHandler().handle(job);
    }
}

如果接口被声明为包私有,它也可能只是在包级别。你可能想把它塞进一个类的唯一原因是它与类本身的耦合非常紧密。也许它是某种帮助接口,严格用于对特定类进行单元测试。

如果接口是public,那么将其嵌套通常是个坏主意。因为这样做会增加接口和封闭类之间的耦合。而接口是减少耦合的最佳方式之一!那么为什么要浪费他们的潜力呢?

假设您有一个 mylib-buttons 库,它有一个 Button 类。有一天拥有Button.ClickListener 似乎是个好主意。然后你想在另一个类中重用这个接口,甚至可能在另一个库中。但是,如果不对包含 Button 类的库引入(可能是不必要的)依赖项,您就无法做到这一点。另一方面,如果它是顶级接口,那么您只需将接口提取到另一个库中,例如 mylib-core,而将凌乱的按钮单独留在 mylib-buttons 中。

interfaces 中的嵌套接口有点不同。它们可以是同一设计的一部分,并且可以一起使用。其中一个 cmets 中的@cricket_007 就是一个很好的例子:Map.Entry

  1. 当外部类被接口扩展时会发生什么。它会对嵌套类产生任何影响吗?

这不是很清楚。如何通过接口扩展类?尽管如此,无论您在此处指的是什么,如果您考虑上述事实,您可能可以自己回答:嵌套接口只是类的命名空间范围的一部分,仅此而已。没有任何其他影响。

【讨论】:

  • 我的意思是实施。就像我们有实现接口的外部类,如果对内部类有任何影响,但我发现它不会(对吗?)。谢谢你的回答,让我头脑清醒了一点。
  • @Kubekk,如果其他类实现了您的嵌套接口(假设它不是私有的)?是的,你的内部阶级不会注意到这一点。它们只是同一接口的不同实现。
猜你喜欢
  • 2011-12-03
  • 1970-01-01
  • 1970-01-01
  • 2011-01-24
  • 1970-01-01
  • 1970-01-01
  • 2013-02-28
  • 2012-02-24
  • 1970-01-01
相关资源
最近更新 更多