在尝试理解java中的接口时,我很难获得“ahaaa”时刻。 根据java教程网站,他们在接口部分说:
通常,公司销售包含复杂的软件包 另一家公司希望在自己的软件产品中使用的方法。 一个例子是一套数字图像处理方法 被出售给制作最终用户图形程序的公司。图片 处理公司编写其类来实现一个接口 它向客户公开。然后图形公司调用 使用签名和返回类型的图像处理方法 在界面中定义。虽然图像处理公司的API是 公开(对其客户),其API的实施保持 作为一个严密保密的秘密 - 事实上,它可能会修改实施 只要它继续实施原件,在以后的日期 客户依赖的界面。
我的问题与上述解释有关。
当他们说:Typically, a company sells a software package that contains complex methods that another company wants to use in its own software product
我很困惑。假设我已经定义了接口,并且我有实现该接口的实现类。我的客户将如何使用我正在创建的API?它不像他们可以访问我的实现类,因为根据上面的描述,implementation of the API is kept as a closely guarded secret
。这是否意味着我向客户提供的所有内容都是使用多种方法定义的接口。实际的实施需要由客户完成?请详细说明这个概念和界面的使用。我不太清楚。谢谢和抱歉noob问题
答案 0 :(得分:4)
也许一个例子可以提供帮助。
假设您有以下类/接口:
public interface ImageApi {
Image create(int width, int height, Color c);
}
class ImageApiImpl implements ImageApi {
@Override
public Image create(int width, int height, Color c) {
... // implementation
}
}
public ImageApiFactory {
public static ImageApi getImageApi() {
return new ImageApiImpl();
}
}
客户可以通过以下方式使用此Api:
ImageApi api = ImageApiFactory.getImageApi();
Image image = api.create(128, 128, Color.Blue);
现在让我们假设开发此API的公司找到了一种更快的创建图像的方法。不幸的是,新方法仅适用于Windows系统。他们可以做到以下几点:
class FastImageApiImpl implements ImageApi {
@Override
public Image create(int width, int height, Color c) {
... // faster windows specfic implementation
}
}
public ImageApiFactory {
public static ImageApi getImageApi() {
if (isWindowsSystem()) {
return new FastImageApiImpl();
}
return new ImageApiImpl();
}
}
客户端代码保持不变,因为两个API实现共享相同的接口。客户不了解具体实施。
答案 1 :(得分:2)
仅使用接口而不了解实现的一个很好的例子是用于与数据库交互的Java JDBC(查询,插入,删除,更新等)。
一旦建立了与数据库的连接(我稍后会解释),用户就会引用一个Connection
实例作为接口。该接口具有创建各种SQL语句(工厂方法)的方法,这些方法返回Statement
接口的实现,该接口在执行时返回ResultSet
接口的实现等。
从用户的角度来看,所有这些对象只能通过界面进行交互。用户不知道或不关心实际的类名或实现细节是什么。
每个数据库公司都有自己专有的方式来实现他们不想与外人共享的一般数据库功能。 Java的创建者不可能为每种类型的数据库实现每种可能的数据库实现,并且肯定不能实现在编写JDBC时(或将来会存在)时尚不存在的数据库类型。
因此,Java没有任何JDBC接口实现,只有接口定义。如果要使用JDBC与特定数据库进行通信,则需要提供一个附加的jar文件,其中包含该数据库的接口实现。一旦这些jar在类路径上,您就可以使用JDBC DriverManager
注册该实现,以便它知道要使用哪些实现。
这有一个额外的好处,即能够非常轻松地更改数据库实现,而无需更改使用JDBC Connection
或Statement
或ResultSet
的任何代码,您只需提供DriverManager一个新的罐子。 (假设您的语句不使用仅由某些数据库公司支持的非标准SQL)