我认为这是一个非常愚蠢的问题,但我无论如何也不能理解这样一个事实:API(如Java Sound API)和包(如Sound API中的javax.sound.sampled )包含接口,并且这些接口中的方法可以方便地调用。
如果接口没有方法定义,调用的是什么?
发布于 2012-04-21 04:04:53
您应该阅读有关Java Sound API及其服务提供者接口的文档。Chapter 1 of the Java Sound API Guide解释了应用程序接口的设计、实现以及通过实现服务提供者接口的不同提供者可以扩展实现的方式。
简而言之,接口的实现是存在的,但应用程序开发人员不能直接访问这些类。
在Java6(在Windows中)中,默认的Java Sound实现是由rt.jar中包含的com.sun.media.sound包和名为jsound*.dll的DLL实现的。SPI模型允许其他服务提供商替换或扩展实现。我找到了this的其他StackOverflow答案,它解释了Java中的SPI模型是如何工作的
发布于 2012-04-21 00:53:53
您不能实例化接口,只能实例化实现接口的类。
private Clip m_clip;这不会实例化或调用任何东西。它只是声明了一个变量,您可以在其中存储对实现Clip接口(或null)的对象的引用。
发布于 2012-04-21 00:54:44
对象可以用接口类型声明,但只能用具体类型初始化。所以
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();它的实现被更改了,但它的客户端仍然可以使用它,而不需要在代码中进行任何更改。
https://stackoverflow.com/questions/10250261
复制相似问题