更彻底的抽象:接口
抽象类是从多个类中抽象出来的模板,如果将这种抽象进行得更彻底,则可以提炼出一种更加特殊的“抽象类”--接口(interface),接口里不能包含普通方法,接口里的所有方法都是抽象方法。
1 接口的概念
接口是从多个相似类中抽象出来的规范,接口不提供任何实现。接口体现的是规范和实现分离的设计哲学。
接口定义的是多个类共同的公共行为规范,这些行为是与外部交流的通道,这就意味着接口里通常是定义一组公用的方法。
2 接口的定义
和类定义不同,定义接口不再使用class关键字,而是使用interface关键字。接口定义的基本语法:
[修饰符] interface 接口名 extends 父接口1,父接口2,......
{
零到多个常量定义...
零个到多个抽象方法定义...
}
修饰符:修饰符可以是public或者省略,如果省略了public访问修饰符,则默认采用包权限访问修饰符,即只有在相同包结构下才可以访问该接口。
接口名:接口名应与类名采用相同的命名规则,即如果仅从语法角度来看,接口名只要是合法的标识符即可。
一个接口可以有多个直接父接口,但接口只能继承接口,不能继承类。
由于接口定义的是一种规范,因此接口里不能包含构造器和初始化块。
接口里只能包含Field(只能是常量),方法(只能是抽象实例方法),内部类(包括内部接口,枚举)定义。
3 接口的继承
interface interfaceA{ int PROP_A = 5; void testA(); }
interface interfaceB{ int PROP_B = 6; void testB(); }
interface interfaceC extends interfaceA,interfaceB{ int PROP_C = 7; void testC(); }
public class InterfaceExtendsTest { public static void main(String[] args) { System.out.println(interfaceC.PROP_A); System.out.println(interfaceC.PROP_B); System.out.println(interfaceC.PROP_C); } } |
4 使用接口
接口不能用于创建实例,但接口可以用于声明引用类型的变量。
当使用接口来声明引用类型变量时,这个引用类型变量必须引用到其实现类的对象。除此之外,接口的主要用途就是被实现类实现。
一个类可以实现一个或多个接口,继承使用extends关键字,实现则使用implements关键字。
因为一个类可以实现多个接口,这也是java为单继承灵活性不足所做的补充。
语法:
[修饰符] class 类名 extends 父类 implements 接口1,接口2....{
}
实现接口与继承父类相似,一样可以获得所实现接口里定义的常量Field,抽象方法,内部类和枚举类定义。
一个类实现了一个或多个接口之后,这个类必须完全实现这些接口里所定义的全部抽象方法。
否则,该类将保留从父接口那里继承到的抽象方法,该类也必须定义为抽象类。
5 接口和抽象类
接口和抽象类很像,它们都有如下特征:
接口和抽象类都不能被实例化,它们都位于继承树的顶端,用于被其他类实现和继承。
接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。
差别:
接口里只能包含抽象方法,不包含已经提供实现的方法;抽象类则完全可以包含普通方法;
接口里不能定义静态方法,抽象类里可以定义静态方法;
接口里只能定义静态常量Field,不能定义普通Field。抽象类里则即可以定义普通Field,也可以定义静态常量Field;
接口里不包含构造器,抽象类里可以包含构造器。抽象类里的构造器并不是用于创建对象,而是让其子类调用这些构造器来完成属于抽象类的初始化操作。
接口里不能包含初始化块,但抽象类则完全可以包含初始化块。
一个类最多只能由一个直接父类,包括抽象类。但一个类可以直接实现多个接口,通过实现多个接口可以弥补java单继承的不足。