一、接口的概念和基本特征
在Java语言中,接口有两种意思:
一是指概念性的接口,即指系统对外提供的所有服务。类的所有能被外部使用者访问的方法构成了类的接口。
二是指用interface关键字定义的实实在在的接口,也成为接口类型。它用于明确的描述系统对外提供的所有服务,能够更加清晰的把系统的实现细节与接口分离。
接口对其成员变量和方法做了许多限制。接口的特征归纳如下:
(1)接口中的成员变量和变量默认都是public、static、final类型的,必须被显示初始化。
(2)接口中的方法默认都是public、abstract类型的。
(3)接口中只能包含public、static、final类型的成员变量和public、abstract类型的成员方法。
(4)接口没有构造方法,不能别实例化。
(5)一个接口不能实现另一个接口,但它可以继承多个其他接口。
(6)接口必须通过类来实现它的抽象方法。
(7)与子类继承抽象父类相似,当类实现了某个接口时,它必须实现接口中所有的抽象方法,否则这个类必须被定义为抽象类。
(8)不允许创建接口的实例,但允许定义接口类型的引用变量,该变量引用实现了这个接口的类的实例。
(9)一个类只能继承一个直接的父类,但能实现多个接口。
二、比较抽象类与接口
抽象类与接口都位于继承树的上层。它们具有一下相同点:
(1)代表系统的抽象层。
(2)都不能被实例化。
(3)都能包含抽象方法。
抽象类和接口主要有两大区别:
(1)在抽象类中可以为部分方法提供默认的实现,从而避免在子类中重复实现它们,提高代码的可重用性,这是抽象类的优势所在;而接口中只能包含抽象方法。
由于抽象类中允许加入具体的方法(即非抽象方法),因此扩展抽象类的功能,即向抽象类中添加一个具体的方法,不会对它的子类造成影响;而对于接口,一旦接口被公布,就必须非常稳定,因为随意在接口中添加抽象方法,会影响到所有的实现类,这些实现类要么实现新增的抽象方法,要么声明为抽象类。
(2)一个类只能继承一个直接的父类,这个父类有可能是抽象类;但一个类可以实现多个接口,这是接口的优势所在。
为了简化系统结构和动态绑定机制,Java语言禁止多继承。借助接口,可以方便地对已经存在的系统进行自下而上的抽象。对于任意两个类,不管它们是否属于同一个父类,只要它们存在着相同的功能,就能从中抽象出一个接口类型。接口中定义了系统对外提供的一组相关的服务,接口并不强迫它的实现类在语义上是同一种类型。
综上所述,接口和抽象类各有优缺点,开发人员应该扬长避短,发挥接口和抽象类各自的长处。使用接口和抽象类的总的原则如下:
(1)用接口作为系统与外界交互的窗口。站在外界使用者的角度,接口向使用者承诺系统能提供哪些服务;站在系统本身角度,接口指定系统必须实现哪些服务。接口是系统中最高层次的抽象类型。
(2)由于外界使用者依赖系统的接口,并且系统内部会实现接口,因此接口本身必须十分稳定,接口一旦制定,就不允许随意修改,否则会对外界使用者及系统内部都造成影响。
(3)用抽象类来制定系统中的扩展点。可以把抽象类看做介于“抽象”和“实现”之间的半成品,抽象类力所能及的完成了部分实现,但该有一些功能有待于它的子类去实现。
三、与接口相关的设计模式