Interface inside class

2019-05-29 19:17发布

问题:

What's the difference between using interface inside class, inside nested class and outside class.

As I was reading about the class DataStructure.java in Questions and Exercises: Nested Classes at Oracle (pasting here fragment of the example):

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. So as the code about shows there is no any body in interface. Couldn't I just extends EvenIterator class with java.util.Iterator<Integer> instead of creating this interface and implements it?

  2. Is there any other difference (aside from code readability) between declaring interference outside/inside class?

  3. What will happen when the outer class gonna be extended by a interface. Will it impact in any way on nested class?

Just want to be sure about these things to know how to use them properly, thanks for your time.

回答1:

  1. So as the code about shows there is no any body in interface. Couldn't I just extends EvenIterator class with java.util.Iterator instead of creating this interface and implements it?

Yes, you could. But this way it may be more readable and extendable. Even if there are no members now, they may be added later.

  1. Is there any other difference (aside from code readability) between declaring interference outside/inside class?

A nested interface is implicitly static, so the only effect is that a nested interface is a part of the enclosing class namespace-wise.

Because members of a class may be declared as protected or private, that applies to nested interfaces as well. It rarely makes sense to use private interfaces, though, because they can only be implemented in the same class, so why bother with interfaces in the first place? However, protected interfaces may be useful. For example, you may have an abstract factory method that is used by the subclasses to provide instances to the parent class. Here's a contrived example:

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);
    }
}

If the interface is declared package-private, it might as well just be at the package level. The only reason you may want to cram it inside a class is because it's very tightly coupled to the class itself. Perhaps it's some sort of helper interface that is used strictly in unit testing that particular class.

If the interface is public, then it's usually a bad idea to make it nested. Because by doing that, you increase coupling between the interface and the enclosing class. And interfaces are one of the best ways to reduce coupling! So why waste their potential?

Suppose you have a mylib-buttons library that have a Button class. One day having a Button.ClickListener seems to be a nice idea. Then you want to reuse this interface in another class, and possibly even in another library. But you can't do it without introducing a (probably unnecessary) dependency on the library that contains the Button class. On the other hand, if it's a top-level interface, then you just extract the interfaces into another library, say, mylib-core, leaving the messy buttons alone in the mylib-buttons.

Nested interfaces inside interfaces is a bit different story. They can be a part of the same design and intended to be used together. @cricket_007 in one of the comments gives a good example of that: Map.Entry.

  1. What will happen when the outer class gonna be extended by a interface. Will it impact in any way on nested class?

This is not exactly clear. How can a class be extended by an interface? Nevertheless, whatever you meant here, you can probably answer it yourself if you consider the aforementioned fact: the nested interface is just a part of the class' namespace scope, and that's it. There are no other impacts whatsoever.