一、什么是面向接口编程
要正确地使用Java语言进行面向对象的编程,从而提高程序的复用性,增加程序的可维护性、可扩展性,就必须是面向接口的编程。面向接口的编程就意味着:开发系统时,主体构架使用接口,接口构成系统的骨架。这样就可以通过更换实现接口的类来更换系统的实现。
例如:在上节示例中,Java接口Introduceable就是系统骨架的一个重要组成部分,这个Java接口定义了一个方法:detailo中心类和教员类分别实现了Java接口Introduceable,因此具有了不同的detail方法实现。在School2类中,print方法接收的参数类型是Introduceable,这样,就可以向print方法传递任意一个Introduceable接口的实现类,在运行时,Java虚拟机会根据实际创建的对象类型调用不同的方法实现。这就意味着:可以通过更换实现接口的类来更换系统的实现。
二、面向接口编程的示例
接下来通过一个示例详细讲解面向接口编程的实现过程。
案例需求的效果图如图1所示。
升级系统,要求如下:
★ 打印机有多种类型,比如:黑白打印机、彩色打印机等。
★ 中心可能配备其中任意一款打印机,负责打印教员或者中心的详细信息。
★ 系统要具备良好的可扩展性与可维护性。
图1 使用不同类型的打印机进行打印
采用面向接口编程的方式实现可以分为3个步骤。
1.抽象出Java接口
分析:由于黑白、彩色打印机都存在一个共同的方法特征:print,而且黑白、彩色打印机对print方法有各自不同的实现,因此可以抽象出一个Java接口PrinterFace(代表打印机),在其中定义print方法。
具体实现代码如下:
折叠
Java 代码
package Java.sg.ch03;
publicinterfacePrinterFace {
//定义打印方法
publicvoicl print (String content);
}
2.实现Java接口
分析:在第一步中已经抽象出Java接口PrinterFace,并在其中定义了print方法。由于黑白、彩色打印机对print方法有各自不同的实现,因此在第2步中,要让黑白、彩色打印机实现PrinterFace接口,各自实现print方法。
彩色打印机代码实现如下:
折叠
Java 代码
package Java.sg.ch03;
publicclassColorPrinterimplements
PrinterFace {
/**
* 打印方法
*/
publicvoidprint(String content) {
System.out.println("彩色打印 :");
System.out.println(content);
}
}
黑白打印机代码实现如下:
折叠
Java 代码
package Java.sg.ch03;
publicclassBlackPrinterimplements
PrinterFace {
/**
* 打印方法
*/
publicvoidprint(String content) {
System.out.println("黑白打印 :");
System.out.println(content);
}
}
3.使用Java接口
经验:现在,Java接口及其实现类都已经创建完毕,接着,我们就要使用面向接口编程的原则,让接口构成系统的骨架,以便达到更换实现接口的类就可以更换系统的实现的目的。
中心类负责对外提供打印功能,要求可以随时更换打印机类型。代码实现如下:
折叠
Java 代码
package Java.sg.ch03;
publicclassSchool3implementsIntroduceable{
privatePrinterFace printer;//打印机
// 输出中心的详细信息
publicString detail() {
return"这里是中心";
}
// 使用中心打印机打印信息
publicvoidprint(Introduceable intro){
printer.print(intro.detail());
}
//设置打印机
publicvoidsetPrinter(PrinterFace p) {
this.printer = p;
}
}
测试类提供main方法进行单元测试。代码实现如下:
折叠
Java 代码
/*
* jsp.sg.ch04.Test.java
* 2011-5-29
* 4u^j2JavaJavaL
*/
packageJava.sg.ch03;
publicclassTest {
publicstaticvoidmain(String[] args) {
//创建中心实例
School3 school =newSchool3();
//为该中心配备黑白打印机
school.setPrinter(newBlackPrinter());
school.print(school);
//为该中心配备彩色打印机
school.setPrinter(newColorPrinter());
school.print(school);
}
}
经验:面向接口编程可以实现接口和实现的分离,这样做的最大好处就是能够在客户端未知的情况下修改实现代码。那么什么时候应该抽象出Java接口呢?一种是用在层和层之问的调用。层和层之间是最忌讳耦合度过高或是改变过于频繁。设计优秀的接口能够解决这个问题。另一种是用在那些不稳定的部分上。如果某些需求的变化性很大,那么定义接口也是一种解决之道。设计良好的接口就像是我们日常使用的万用插座一样,不论插头如何变化,都可以使用。
最后强调一点,良好的接口定义一定是来自于需求的,它绝对不是程序员绞尽脑汁想出来的。