【发布时间】:2012-05-02 06:38:59
【问题描述】:
我认为这是一个非常愚蠢的问题,但我终其一生都无法理解 API(例如 Java Sound API)和包(例如 javax.sound.sampled Sound API 中)包含接口,这些接口中的方法可以方便地调用。
如果接口没有方法定义,调用什么?
【问题讨论】:
标签: java api audio interface package
我认为这是一个非常愚蠢的问题,但我终其一生都无法理解 API(例如 Java Sound API)和包(例如 javax.sound.sampled Sound API 中)包含接口,这些接口中的方法可以方便地调用。
如果接口没有方法定义,调用什么?
【问题讨论】:
标签: java api audio interface package
您应该阅读有关 Java Sound API 及其服务提供者接口的文档。 Chapter 1 of the Java Sound API Guide 解释了 API 的设计、实现以及实现服务提供者接口的不同提供者可以扩展实现的方式。
简而言之,接口的实现是存在的,但应用程序开发人员无法直接访问这些类。
在 Java 6(在 Windows 中)中,默认的 Java Sound 实现由 rt.jar 中包含的 com.sun.media.sound 包和名为 jsound*.dll 的 DLL 实现。 SPI 模型允许其他服务提供者替换或扩展实现。我发现 this 其他 StackOverflow 答案解释了 SPI 模型如何在 Java 中工作
【讨论】:
不能实例化接口,只能实例化实现接口的类。
private Clip m_clip;
这不会实例化或调用任何东西。它只是声明了一个变量,您可以在其中存储对实现Clip 接口(或null)的对象的引用。
【讨论】:
对象可以用接口类型声明,但只能用具体类型初始化。所以
private Clip m_clip;
很好,因为它只是一个声明。在使用m_clip之前,你需要初始化它,即让它指向一个有效的对象。
m_clip = new Clip();
会产生编译错误,因为Clip,作为一个接口,不能被实例化。然而,
class MyClip implements Clip { ... }
...
m_clip = new MyClip();
没问题:MyClip 是一个实现Clip 接口的具体(非抽象)类,因此可以在需要Clip 时对其进行实例化和使用。在此语句之后,m_clip 的静态类型为Clip(这是编译器在编译时知道的类型,m_clip 的客户端也是如此),但它的动态或运行时类型是MyClip。这不会被编译器跟踪,m_clip 的客户端也不一定知道。根据这个简单的例子,这可能看起来很奇怪,但考虑到实际的对象可能是从一个方法返回的,该方法可以在另一个类中,不是你写的,所以没有人知道里面发生了什么。使用的具体类型甚至可能对外界不可见。
一旦你初始化了m_clip,它的客户就可以使用它(例如调用它的方法)。但他们只看到它的公共接口,即Clip 中声明的方法。这一切听起来可能很复杂,但它有一个巨大的优势:m_clip 的实际(运行时)类型可以随时更改,而不会影响其客户端。通过将上面的行更改为
m_clip = new SomeOtherClip();
它的实现已经改变,但它的客户仍然可以使用它,而无需更改其代码中的任何内容。
【讨论】: