(十一)JAVA基础学习第十一篇章——抽象类与接口

设计良好的软件系统应该具备“可复用性”和“可扩展性”,能够满足用户需求的不断变更。使用抽象类和接口是实现“可复用性”和“可扩展性”重要的设计手段。

抽象类

Java语言提供了两种类:一种是具体类;另一种是抽象类。
抽象类的概念
在Java中具有抽象方法的类称为“抽象类”。
抽象类的声明和实现
在Java中抽象类和抽象方法的修饰符是abstract。例如:
(十一)JAVA基础学习第十一篇章——抽象类与接口
注意:如果一个方法被声明为抽象的,那么这个类也必须被声明为抽象的。而一个抽象类中,可以有0~n个抽象方法,以及0-n个具体方法。设计抽象方法的目的就是让子类来实现,否则抽象方法就没有任何意义。抽象类不能被实例化,只有具体类才能被实例化。

接口

比抽象类更加抽象的是接口,在接口中所有的方法都是抽象的。
提示:Java 8 之后接口中新增加了默认方法,因此“接口中所有的方法都是抽象的”这个提法在Java 8 之后是有待商榷的。
接口的声明和实现
在Java中接口的声明使用的关键字是interface。
(十一)JAVA基础学习第十一篇章——抽象类与接口
注意:在接口中成员变量都是静态成员变量,即省略了public static final修饰符。
某个类实现接口时,要在声明时使用implements关键字,当实现多个接口时,其之间用逗号分隔。实现接口时要实现接口中声明的所有方法。
(十一)JAVA基础学习第十一篇章——抽象类与接口
接口继承
Java语言中允许接口和接口之间继承。由于接口中的方法都是抽象方法,所以继承之后也不需要做什么。接口之间的继承也是使用关键字extends。如果接口A继承了接口B,类C实现接口A,就要实现接口A和接口B中的所有方法。
Java 8 新特性默认方法和静态方法
在Java 8 之前,尽管Java语言中接口已经非常优秀了,但相比其他面向对象语言而言,Java接口存在如下不足之处:
(1)不能可选实现方法,接口的方法全部是抽象的,实现接口时必须全部实现接口中的方法,哪怕是有些方法并不需要,也必须实现。
(2)没有静态方法。
针对这些问题,Java 8 在接口中提供了声明默认方法和静态方法的能力。例如:
(十一)JAVA基础学习第十一篇章——抽象类与接口
在接口InterfaceA中声明了两个抽象方法methodA和methodB,两个默认方法methodC和methodD,还声明了静态方法methodE。接口中的默认方法类似于类中具体方法,给出了具体实现,只是方法修饰符是default。接口中的静态方法类似于类中的静态方法。
(十一)JAVA基础学习第十一篇章——抽象类与接口
实现接口时接口中原有的抽象方法在实现类中必须实现。默认方法可以根据需要有选择的实现(覆盖)。静态方法不需要实现,实现类中不能拥有接口中的静态方法。
(十一)JAVA基础学习第十一篇章——抽象类与接口
注意:调用接口静态方法只能通过接口名(InterfaceA)调用,不能通过实现类ABC调用,可以理解为接口中声明的静态方法与其他实现类没有任何关系。

抽象类与接口的区别

抽象类与接口的区别如下:
(1)接口支持多继承,而抽象类(包括具体类)只能继承一个父类。
(2)接口中不能有实例成员变量,接口所声明的成员变量全部是静态常量,即便变量不加public static final 修饰符也是静态常量。抽象类与普通类一样,各种形式的成员变量都可以声明。
(3)接口中没有包含构造方法。由于没有实例成员变量,也就不需要构造方法。抽象类中可以有实例成员变量,也需要构造方法。
(4)抽象类中可以声明抽象方法和具体方法。Java 8 之前接口中只有抽象方法,而Java 8 之后接口中也可以声明具体方法,具体方法通过声明默认方法实现。
提示:在多数情况下接口不能替代抽象类,例如,当需要维护一个对象的信息和状态时只能使用抽象类,而接口不行,因为维护一个对象的信息和状态需要存储在实例成员变量中,而接口中不能声明实例成员变量。