我认为这是一个非常愚蠢的问题,但是对于我的生活,我不能理解API(例如Java Sound API)和包(例如javax.sound.sampled)这一事实在Sound API中)包含接口,可以方便地调用这些接口中的方法。
如果一个接口没有方法定义,那么被调用的是什么?
答案 0 :(得分:0)
您无法实例化接口,只能实现接口的类。
private Clip m_clip;
这不会实例化或调用任何东西。它只是声明一个变量,您可以在其中存储对实现Clip
接口(或null
)的对象的引用。
答案 1 :(得分:0)
对象可以使用接口类型声明,但只能使用具体类型进行初始化。所以
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
(这是编译器在编译时以及{{1}的客户端已知的类型}},但它的动态或运行时类型是m_clip
。这不是由编译器跟踪的,也不是MyClip
的客户端必须知道的。基于这个简单的例子,这可能看起来很奇怪,但是考虑到实际对象可能是从一个方法返回的,该方法可以在另一个类中,而不是由你编写,所以没有人知道里面发生了什么。所使用的具体类型甚至可能对外界都不可见。
初始化m_clip
后,其客户端可以使用它(例如调用其方法)。但他们只看到它的公共接口,即m_clip
中声明的方法。这一切听起来都很复杂,但它有一个很好的优势: Clip
的实际(运行时)类型可以随时更改,而不会影响其客户端。例如。通过将上面的行更改为
m_clip
它的实现已更改,但其客户端仍然可以在不更改代码中的任何内容的情况下使用它。
答案 2 :(得分:0)
您应该阅读有关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中工作