JavaSE 18(抽象类和接口)
前言:
接口是为了定义多个类(包括非相关的类)的共同行为。
1. 抽象类:
-
在继承的层次结构中,每个新子类都使类变得越来越明确和具体。如果从一个子类追溯到 父类,类就会变得更通用、更加不明确。类的设计应该确保父类包含它的子类的共同特征。有时候,一个父类设计得非常抽象,以至于它都没有任何具体的实例。这样的类称为抽象类(abstract class)。
-
抽象类和常规类很像,但是不能使用 new 操作符创建它的实例。抽象方法只有定义而没有实现。它的实现由子类提供。一个包含抽象方法的类必须声明为抽象类。
-
抽象类的构造方法定义为 Protected, 因为它只被子类使用。创建一个具体子类的实例时,它的父类的构造方法被调用以初始化父类中定义的数据域。
-
抽象类的几点说明:
1.抽象方法不能包含在非抽象类中。如果抽象父类的子类不能实现所有的抽象方法,那么子类也必须定义为抽象的。换句话说,在抽象类扩展的非抽象子类中,必须实
现所有的抽象方法。2.还要注意到,抽象方法是非静态的。抽象类是不能使用 new 操作符来初始化的。但是,仍然可以定义它的构造方法,这个构造方法在它的子类的构造方法中调用。例如,CeometricObject 类的构造方法在Circle 类和 Recfange 类中调用。
3.包含抽象方法的类必须是抽象的。但是,可以定义一个不包含抽象方法的抽象类。在这种情况下,不能使用 new 操作符创建该类的实例。这种类是用来定义新子类的基类的。
4.子类可以覆盖父类的方法并将它定义为 abstract。这是很少见的,但是它在当父类的方法实现在子类中变得无效时是很有用的。在这种情况下,子类必须定义为abstracto
5.即使子类的父类是具体的,这个子类也可以是抽象的。例如,Object 类是具体的,但是它的子类如 CeometricObject 可以是抽象的。
6.不能使用 new 操作符从一个抽象类创建一个实例,但是抽象类可以用作一种数据类型。因此,下面的语句创建一个元素是 CeometricObject 类型的数组是正确的:
GeometricObject[] objects = new CeometricObject[10];
然后可以创建一个 CeometricObject 的实例并将它的引用陚值给数组,如下所示:
objects[0] - new CircleO;
2. 接 口:
1.
-
接口在许多方面都与抽象类很相似,但是它的目的是指明相关或者不相关类的多个对象的共同行为。例如,使用正确的接口,可以指明这些对象是可比较的、可食用的,以及可克隆的。
-
为了区分接口和类,Java 采用下面的语法来定义接口:
修饰符 interface 接口名 {
/** 常量声明 / /* 方法签名
}
-
下面是一个接口的例子:
modifier interface InterfaceName {
}
-
在 Java 中,接口被看作是一种特殊的类。就像常规类一样,每个接口都被编译为独立的字节码文件。使用接口或多或少有点像使用抽象类。例如,可以使用接口作为引用变M的数据类型或类型转换的结果等。与抽象类相似,不能使用 new 操作符创建接口的实例。
可以使用 Edible 接口来明确一个对象是否是可食用的。这需要使用 implements 关键字让对象的类实现这个接口来完成。
-
类和接口之间的关系称为接口继承( interface inheritance)。因为接口继承和类继承本质上是相同的,所以我们将它们都简称为继承。
compareTo 应该与 equals 保持一致。也就是说,对于两个对象 ol和 o2, 应该确保当且仅当 ol.equals(o2)为 true时 ol.compareTo(o2)»0 成立。
3. Cloneable 接口:
-
经常会出现需要创建一个对象拷贝的情况。为了实现这个目的,需要使用 clone 方法并理解 Cloneable 接口。
-
接口包括常量和抽象方法,但是 Cloneable 接口是一个特殊情况。在 java.lang包中的
Cloneable 接口的定义如下所示:package java.lang;
public interface Cloneable { }
-
这个接口是空的。一个带空体的接口称为标记接口(marker interface)。一个标记接口既不包括常量也不包括方法。
-
它用来表示一个类拥有某些特定的属性。实现 Cloneable 接口的类标记为可克隆的,而且它的对象可以使用在 Object 类中定义的 cloneO 方法克隆。
4. 接口与抽象类:
- 接口的使用和抽象类的使用基本类似,但是,定义一个接口与定义一个抽象类有所不
同。表 13-2 总结了这些不同点。
2.一个实现 Newlnterface 的类必须实现在 Newlnterface, Interfacel, … ,InterfaceN
中定义的抽象方法。接口可以扩展其他接口而不是类。一个类可以扩展它的父类同时实现多个接口。
所有的类共享同一个根类 Object, 但是接口没有共同的根。与类相似,接口也可以
定义一种类型。一个接口类型的变量可以引用任何实现该接口的类的实例。如果一个类实
现了一个接口,那么这个接口就类似于该类的一个父类。可以将接口当作一种数据类型使
用,将接口类型的变量转换为它的子类,反过来也可以。例如,假设 c 是图 13-7 中 CUss2的 一 个 实 例,那 么 c 也 是 Object、Classl、Interfacel、Interfacel_l、Interfacel_2、Interface2_l 和 Interface2_2 的实例。
3. 本章总结:
1.抽象类和常规类一样,都有数据和方法,但是不能用 new 操作符创建抽象类的实例。
2.非 抽 象 类 中 不 能 包 含 抽 象 方 法。如果抽象类的子类没有实现所有被继承的父类抽象方法,就必须将该子类也定义为抽象类。
3.包含抽象方法的类必须是抽象类。但是,抽象类可以不包含抽象的方法。
4.即使父类是具体的,子类也可以是抽象的。
5.接口是一种与类相似的结构,只包含常量和抽象方法。接口在许多方面与抽象类很相近,但抽象类除了包含常量和抽象方法外,还可以包含变量和具体方法。
6.在 Java中,接口被认为是一种特殊的类。就像常规类一样,每个接口都被编译为独立的字节码文件。
7.接口 java.lang.Comparable 定义了 compareTo 方法。Java 类库中的许多类都实现了 Comparable。
8 接口 java.lang.Cloneable 是一个标记接口。实现 Cloneable 接口的类的对象是可克隆的。
9.个类仅能继承一个父类,但一个类却可以实现一个或多个接口。
10.— 个接口可以继承一个或多个接口。