第8章 接口
一、接口的概念和基本特征
1、接口的主要特征包括:
(1)接口中成员变量默认为public/static/final类型的,必须被显式初始化;
(2)接口中方法默认为public/abstract类型的;
(3)接口中只能包含上述public/static/final类型的成员变量和public/abstract类型的方法。在接口中定义实例变量、非抽象的实例方法和静态方法都是非法的,无法通过编译。
(4)接口没有构造方法,不能被实例化。
(5)接口之间不能实现,但可以继承。接口必须通过类来实现它的抽象方法,并且该类必须实现接口中所有的抽象方法,否则必须被定义为抽象类。
(6)接口不能被实例化,但可以定义接口类型的引用变量,该变量引用实现该接口的类的实例。
二、接口与抽象类的异同
1、相同点:(1)都属于系统的抽象层,都无法被实例化。(2)都包含抽象方法,其中接口是必须所有方法均为抽象方法,抽象类至少有一个抽象方法。
2、区别:(1)抽象类中可以提供部分方法的实现,为子类提供方便,提高代码的可重用性。如果向抽象类中增加具体的非抽象方法,那对于其子类都可以直接获得该方法,而不需要子类做出相应调整。而对于接口,如果接口中增加新的抽象方法,那原先实现该接口的类都需要增加该新增方法的实现代码,或者调整为抽象类。(2)一个类只能继承一个直接父类,而一个类可以实现多个接口。
一般而言,接口和抽象类使用原则如下:
(1)用接口作为系统与外界交互的窗口,对于外界使用者而言,接口向使用者承诺系统所能提供的服务,对于系统本身而言,接口指定了系统必须实现的服务。
接口理应是系统中最高层次的抽象类型。
(2)接口必须非常稳定,不得随意修改。
(3)抽象类可设计为定制系统中的扩展点。
三、与接口相关的设计模式
*定制服务模式
以电信公司为个人用户提供的服务为例,公司提供了两种套餐服务,分别为极速精英套餐包括:A宽带上网服务、B在线杀毒服务、C邮箱服务;套餐费用为2999包年或者140包月;金融专网套餐包括:B在线杀毒服务、C邮箱服务、D电信金融专网服务、E网络硬盘服务;套餐费为3000包年或者150包月。
针对这两个套餐,可以分别设计两个接口,各个接口分别包含各自的服务内容。而两个套餐中又包含相同的服务内容,因此也可以设计ABCDE5个接口,然后通过对接口的继承,形成对应于套餐的派生接口。显然后者更为精细化,也使得系统对于接口(服务)的维护变得相对容易。
//A宽带上网
public interface BroadbandService{
connect();
disconnect();
}
//B在线杀毒服务
public interface VirusKillingService{
scanVirus();
}
//C邮箱服务
public interface MailboxService{
sendMail();
receiveMail();
writeMail();
deleteMail();
}
//D电信金融专网服务
public interface FinancialNetworkService{
exchangeStock();
exchangeCheck();
}
//E网络硬盘服务
public interface NetworkDiskService{
write();
read();
}
前述两种套餐通过接口的继承来描述
//极速精英套餐
public interface SuperSpeedCombo extends BroadbandService,VirusKillingService,MailService{
...
}
//金融专网套餐
public interface FinanceCombo extends FinancialNetworkService,VirusKillingService,MailService,NewworkDiskService{
...
}
接口设计完毕后需要实现,为提高代码的可重用性,实现类也须尽量精细化,即对应各个服务接口设计实现类,以宽带服务为例:
public class BroadbandServiceImp1
implements BroadbandService{
private int speed; //网速
public BroadbandServiceImp1(int speed){
this.speed=speed;
}
//连接网络
public void connect(String username,string psw){
...
}
//断开网络
public void connect(){...}
}
对于代表套餐服务的派生复合接口SuperSpeedCombo和FinanceCombo,可以采用组合手段,复用其所继承的接口的实现类的代码,以提高代码的重用率。
以SuperSpeedCombo的实现类为例:
public class SuperSpeedComboImp1
implements SuperSpeedCombo{
//创建基于各服务接口的引用变量作为复合接口实现类的成员
private BroadbandService broadbandService;
private VirusKillingService viruskillingService;
private MailboxService mailboxService;
//构造函数
public SuperSpeedComboImp1(
BroadbandService broadbandService,
VirusKillingService viruskillingService,
MailboxService mailboxService){
this.broadbandService=broadbandService;
this.viruskillingService=viruskillingService;
this.mailboxService=mailboxService;
}
//借助成员变量的方法实现方法
//网络连接
public void connect(String username,String psw){
broadbandService.connect(username,psw);
}
//断开网络
public void disconnect(){
broadbandService.disconnect();
}
//杀毒
public void scanVirus(){
viruskillingService.scanVirus();
}
//发邮件
public void sendMail(){
mailboxService.sendMail();
}
...
}
创建极速精英套餐服务的一个实例:
//先创建各个子服务的实例对象
BroadbandService broadbandService=
new BroadbandServiceImp1(2);
VirusKillingService viruskillingService=
new virusKillingServiceImp1();
MailboxService mailboxService=
new mailboxServiceImp1(50);
//创建极速精英套餐服务的类实例
SuperSpeedCombo superSpeedCombo=
new SuperSpeedComboImp1
(broadbandService,viruskillingService,mailboxService);