0

我认为这是一个非常愚蠢的问题,但我终其一生都无法理解 API(例如 Java Sound API)和包(例如 Sound 中的 javax.sound.sampled)这一事实。 API)包含接口,这些接口中的方法可以方便地调用。

如果接口没有方法定义,调用什么?

4

3 回答 3

0

您不能实例化接口,只能实例化实现接口的类。

private Clip m_clip;

这不会实例化或调用任何东西。Clip它只是声明了一个变量,您可以在其中存储对实现接口(或null)的对象的引用。

于 2012-04-20T16:53:52.807 回答
0

对象可以用接口类型声明,但只能用具体类型初始化。所以

private Clip m_clip;

很好,因为它只是一个声明。在使用之前m_clip,需要对其进行初始化,即使其指向一个有效的对象。

m_clip = new Clip();

会产生编译错误,因为作为Clip接口,无法实例化。然而,

class MyClip implements Clip { ... }
...
m_clip = new MyClip();

可以:MyClip是实现接口的具体(非抽象)类Clip,因此可以在需要时实例化和使用它Clip。在此语句之后, is 的静态类型这是编译器在编译时知道的类型,也是客户端知道的类型),但它的动态或运行时类型是. 这不是由编译器跟踪的,也不一定是客户端知道的。m_clipClipm_clipMyClipm_clip. 根据这个简单的例子,这可能看起来很奇怪,但考虑到实际的对象可能是从一个方法返回的,该方法可以在另一个类中,不是你写的,所以没有人知道里面发生了什么。使用的具体类型甚至可能对外界不可见。

一旦你初始化m_clip,它的客户就可以使用它(例如调用它的方法)。但是他们只看到它的公共接口,即在. 中声明的方法Clip。这一切听起来可能很复杂,但它有一个了不起的优势:可以随时更改实际(运行时)类型,而不会影响其客户端。m_clip例如,通过将上面的行更改为

m_clip = new SomeOtherClip();

它的实现发生了变化,但它的客户仍然可以使用它,而无需更改其代码中的任何内容。

于 2012-04-20T16:54:44.140 回答
0

您应该阅读有关 Java Sound API 及其服务提供者接口的文档。Java Sound API Guide 的第 1 章解释了 API 的设计、实现以及实现服务提供者接口的不同提供者可以扩展实现的方式。

简而言之,接口的实现存在,但应用程序开发人员无法直接访问这些类。

在 Java 6(在 Windows 中)中,默认的 Java Sound 实现由 rt.jar 中包含的 com.sun.media.sound 包和名为 jsound*.dll 的 DLL 实现。SPI 模型允许其他服务提供者替换或扩展实现。我找到另一个 StackOverflow 答案,它解释了 SPI 模型在 Java 中的工作原理

于 2012-04-20T20:04:53.047 回答