2016-02-08 39 views

回答

6

你这样做是为了防止其他人访问您的实现类获取有关接口的详细信息。例如,你可以隐藏你的实现类型库中,给类型包访问,并返回你的接口的实例到库的用户:

// 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() { 
     ... 
    } 
} 

您的客户获取的对象是这样的:

public class MyFactory { 
    static SomeInterface make() { 
     // MyFactory can see MyImplementation 
     return new MyImplementation(); 
    } 
} 

这个技巧在实现使用大量库时变得有用。您可以高效地将库的接口与其实现进行分离,以便用户不必知道库的内部依赖关系。

+3

我没有看到向用户提交一个接口与向用户提供实现类之间的区别。 “外观和感觉”是一样的... – Nitek

+1

@Nitek:这里有一个例子解决了这个问题,OP希望公开的方法暴露给最终用户不想公开的测试:http:/ /stackoverflow.com/a/6913509/217324 –

+0

@Nitek这不是关于外观和感觉,而是关于将你图书馆的用户与他们不应该看到的东西隔离。 – dasblinkenlight

-3

接口可以由多个类来实现。没有规定只有一个类可以实现这些。接口提供了对java的抽象。

http://www.tutorialspoint.com/java/java_interfaces.htm 你可以从这个链接

+3

这是一个“链接 - 仅回答“,这被认为是StackOverflow上的错误形式,因为链接不好。问问自己,如果没有链接,答案会是多么的好。除非你准备好让自己的答案足够独立,否则它应该是一个评论。 –

+0

我不认为提问者认为你在一个实现类中是有限的。我认为他们更想知道为什么有人会在只有一个实现类的情况下拆分接口。 –

0

其中一个原因是保持开放/关闭原则,其中规定您的代码应该打开以进行扩展,但关闭以进行修改。尽管你现在只有一个实现类,但是随着时间的推移,你将需要另一个不同的实现类。如果事先将实现提取到接口中,则只需编写另一个实现类即。您无需修改​​完善的代码,消除了引入错误的风险。

0

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

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

public interface MyInterface { 
    void aMethod1(); 
    void aMethod2(); 
} 

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

你也有一个不相关的类有自己的层次:

public class SomeClass extends SomeOtherClass { 
... 
} 

现在你想SomeClassMyInterface类型,但你还想继承MyInterfaceImpl中已有的所有代码。既然你不能既延长和SomeOtherClassMyInterfaceImpl,可以实现接口和使用委托:

public class SomeClass extends SomeOtherClass implements MyInterface { 
    private MyInterface myInterface = new MyInterfaceImpl(); 

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

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

要尊重接口分离原则。

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

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

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

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

如果您正在定义的类实现单个接口,那么该接口将不得不代表收集和存储系统的需求。这会导致,例如:

  • 集合的单元测试必须写入实现Storable的对象,增加复杂度级别。如果稍后需要显示对象时,您将不得不将显示代码所需的方法添加到单个接口,并修改测试的收集和存储以实现显示所需的方法。

我在此讨论对测试代码的影响。如果其他生产级别的对象需要存储并且不显示,问题会更大。项目规模越大,不尊重界面隔离原则所产生的问题就越大。

相关问题