关于java:当只有一个实现类时,为什么要使用接口?

Why should I use an interface when there is only one implementation class?

我是编程新手,我正在学习Java。
我只是想知道为什么我应该在只有一个实现类时使用接口?


这样做是为了防止其他人访问您的实现类型。例如,您可以在库中隐藏实现类型,提供类型包访问,并将接口实例返回给库的用户:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// This is what the users of your library know about the class
// that does the work:
public interface SomeInterface {
    void doSomethingUseful();
    void doSomethingElse();
}

// This is the class itself, which is hidden from your clients
class MyImplementation implements SomeInterface {
    private SomeDependency dependency = new SomeDependency();
    public void doSomethingUseful() {
        ...
    }
    public void doSomethingElse() {
        ...
    }
}

您的客户获得如下对象:

1
2
3
4
5
6
public class MyFactory {
    static SomeInterface make() {
        // MyFactory can see MyImplementation
        return new MyImplementation();
    }
}

当实现使用大量库时,这个技巧变得有用。您可以有效地将库的接口与其实现分离,以便用户不必了解库内部的依赖项。


尊重接口隔离原则。

创建接口的决定不应该基于实现类的数量,而应该基于使用对象的不同方式的数量。使用对象的每种方式都由接口表示,接口由使用它的代码定义。假设您的对象需要存储在内存中,保存在按顺序保存对象的集合中。同一个对象也需要存储在一些持久存储中。

假设您首先实现持久性。存储系统需要的是持久对象的唯一标识符。使用方法getUniqueId创建一个接口,比如Storable。然后,您实现存储。

然后,您实现该集合。您可以使用方法compareTo从接口中的存储对象(如Comparable)定义集合所需的内容。然后,您可以依赖Comparable实现集合。

您要定义的类将实现两个接口。

如果要定义的类实现单个接口,则该接口必须表示集合和存储系统的需要。这会导致,例如:

  • 集合的单元测试必须用实现可存储的对象编写,增加了复杂程度。

  • 如果以后需要显示对象,则必须将显示代码所需的方法添加到单个接口,并修改测试以进行收集和存储,以实现显示所需的方法。

我在这里讨论对测试代码的影响。如果其他生产级别对象需要存储而不显示,则问题会更大。项目越大,不遵守接口隔离原则所产生的问题就越大。


它可以让您灵活地在将来添加更多实现,而无需更改引用该接口的客户端代码。

另一个有用的例子是在需要时在Java中模拟多重继承。例如,假设您有一个接口MyInterface和一个实现:

1
2
3
4
5
6
7
8
9
public interface MyInterface {
  void aMethod1();
  void aMethod2();
}

class MyInterfaceImpl implements MyInterface {
  public void aMethod1() {...}
  public void aMethod2() {...}
}

您还有一个与其自己的层次结构无关的类:

1
2
3
public class SomeClass extends SomeOtherClass {
 ...
}

现在,您希望SomeClass的类型为MyInterface,但您还希望继承MyInterfaceImpl中已存在的所有代码。由于无法扩展SomeOtherClassMyInterfaceImpl,因此可以实现接口并使用委托:

1
2
3
4
5
6
7
8
9
10
11
12
public class SomeClass extends SomeOtherClass implements MyInterface {
  private MyInterface myInterface = new MyInterfaceImpl();

  public void aMethod1() {
    myInterface.aMethod1();
  }

  public void aMethod2() {
    myInterface.aMethod2();
  }
  ...
}

一个原因是保持开放/封闭原则,该原则指出您的代码应该是可以扩展的,但是关闭以进行修改。虽然你现在只有一个实现类,但是随着时间的推移,你可能需要另一个不同的实现类。如果事先将实现提取到接口中,则只需编写另一个实现类即。您无需修改??完美的代码,从而消除了引入错误的风险。


接口可以由多个类实现。没有规则只有一个类可以实现这些。接口为java提供抽象。

http://www.tutorialspoint.com/java/java_interfaces.htm
您可以从此链接获取有关接口的更多信息