Java Interface接口用法详解(附带实例)
Java 程序中,如果一个抽象类中的所有方法都是抽象的,就可以将这个类用另外一种方式来定义,也就是接口(Interface)。
接口是抽象方法和常量值的定义的集合。从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。
接口中只能进行方法的声明,不提供方法的实现,在接口中声明的方法具有 public 和 abstract 属性:
接口可以由类来实现,类通过关键字 implements 声明使用一个或多个接口。所谓实现接口,就是实现接口中声明的方法。一个类可以在继承另一个类的同时实现多个接口。
实现接口的语法格式如下:
如果某个接口方法没有被实现,实现类中必须将它声明为抽象的,该类当然也必须声明为抽象的:
如上例中,主板提供了 PCI 插槽,只要一个声卡或者网卡遵循 PCI 规范,就可以插入 PCI 插槽中,并与主板正常通信。至于这个声卡或者网卡是哪个厂商生产的,内部是如何实现的,主板都不关心。这就是面向接口的编程。在开发系统时,主体构架使用接口,接口构成系统的骨架,这样就可以通过更换接口的实现类来更换系统的实现。
二者的区别可以归纳为以下五点:
总体来说,抽象类和接口都用于为对象定义共同的行为,二者在很大程度上可以互相替换。但由于抽象类只允许单继承,所以当二者都可以使用时,优先考虑接口。只有当需要定义子类的行为,并为子类提供共性功能时,才考虑使用抽象类。
接口是抽象方法和常量值的定义的集合。从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。
Java接口的声明
接口声明的语法格式如下:public interface 接口名 extends 父接口名字 { [public] [static] [final] 常量; [public] [abstract] 方法; }常量定义部分定义的常量均具有 public、static 和 final 属性。
接口中只能进行方法的声明,不提供方法的实现,在接口中声明的方法具有 public 和 abstract 属性:
public interface PCI { final int voltage; public void start(); public void stop(); }
Java接口的实现
接口不能进行实例化,即不能用 new 创建接口的实例。接口可以由类来实现,类通过关键字 implements 声明使用一个或多个接口。所谓实现接口,就是实现接口中声明的方法。一个类可以在继承另一个类的同时实现多个接口。
实现接口的语法格式如下:
class 类名 extends [基类] implements 接口, ..., 接口 { ...... // 成员定义部分 }接口中的方法默认是 public,所以类在实现接口方法时,一定要用 public 来修饰。
如果某个接口方法没有被实现,实现类中必须将它声明为抽象的,该类当然也必须声明为抽象的:
interface IMsg { void Message(); } public abstract class MyClass implements IMsg { public abstract void Message(); }
Java接口的使用
模拟现实世界的计算机组装功能:- 定义计算机主板的 PCI 类,模拟主板的 PCI 通用插槽,有两个方法:start(启用)和 stop(停用)。
- 声明具体的声卡类 SoundCard 和网卡类 NetworkCard,分别实现 PCI 接口中的 start 和 stop 方法,从而实现 PCI 标准的不同部件的组装和使用。
interface PCI{// 这是Java接口,相当于主板上的PCI插槽的规范 void start(); void stop(); } class SoundCard implements PCI{// 声卡实现了PCI插槽的规范,但行为完全不同 public void start(){ System.out.println("Du du du ......."); } public void stop(){ System.out.println("Sound stop!"); } } class NetworkCard implements PCI{// 网卡实现了PCI插槽的规范,但行为完全不同 public void start() { System.out.println("Send ......."); } public void stop() { System.out.println("Network stop!"); } } class MainBoard{ public void usePCICard(PCI p){ // 该方法可使主板插入任意符合PCI插槽规范的卡 p.start(); p.stop(); } } public class Assembler{ public static void main(String args[]){ PCI nc = new NetworkCard(); PCI sc = new SoundCard(); MainBoard mb = new MainBoard(); // 主板上插入网卡 mb.usePCICard(nc); // 主板上插入声卡 mb.usePCICard(sc); } }程序运行结果如图所示:
Send ....... Network stop! Du du du ....... Sound stop!接口只定义类应当遵循的规范,却不关心这些类的内部数据和功能的实现细节。从程序的角度上说,接口只规定类必须提供的方法,从而分离了规范和实现,增强了系统的可扩展性和可维护性。
如上例中,主板提供了 PCI 插槽,只要一个声卡或者网卡遵循 PCI 规范,就可以插入 PCI 插槽中,并与主板正常通信。至于这个声卡或者网卡是哪个厂商生产的,内部是如何实现的,主板都不关心。这就是面向接口的编程。在开发系统时,主体构架使用接口,接口构成系统的骨架,这样就可以通过更换接口的实现类来更换系统的实现。
Java接口和抽象类的关系
抽象类与接口是 Java 语言对于抽象类定义进行支持的两种机制。二者非常相似,但抽象类是对源的抽象,而接口是对动作和规范的抽象。二者的区别可以归纳为以下五点:
- 一个类只能继承一个抽象类,但是可以同时实现多个接口;
- 接口中的方法都是抽象的,而抽象类中可以存在非抽象方法;
- 抽象类中的变量可以是任意数据类型的变量,而接口中的成员变量只能是静态常量;
- 抽象类中可以定义静态方法和静态代码块,接口中不可以;
- 接口可以继承另一个接口,并且可以继承多个接口;而抽象类只能继承一个非抽象类。
总体来说,抽象类和接口都用于为对象定义共同的行为,二者在很大程度上可以互相替换。但由于抽象类只允许单继承,所以当二者都可以使用时,优先考虑接口。只有当需要定义子类的行为,并为子类提供共性功能时,才考虑使用抽象类。