0.1) 本文描述+源代码均 转自 core java volume 1, 旨在理解 java 接口概念 ;
0.2)接口技术: 这种技术主要用来描述类具有什么功能, 并不给出每个功能的具体实现; 一个类可以实现多个接口, 但只允许单继承;
0.3) 最后简单阐述了 接口和抽象类 的 区别;
1.1)接口中的所有方法自动属于public: 故,在接口中声明方法时,不必提供关键字public;
1.2)接口可以包含多个方法: 在接口中还可以定义常量;然而,更重要的是 要知道接口不能提供哪些功能;接口不能提供实例域, 也不能在接口中实现方法, 提供实例域和方法实现的任务应该由实现接口的那个类来完成;因此,可以将接口看做是没有实例域的抽象类,但接口和抽象类还是有区别的, 稍后给出解释;
1.3)为了让类实现一个接口, 需要以下两个steps:
1.4)排序访问必须让它实现 compareTo 方法:我们已经看到, 要让一个类使用排序访问必须让它实现 compareTo 方法,这是理所当然的,因为要向 sort方法提供对象的比较方式;
1.5)但是 , 为什么不能在 Employee类直接提供一个 compareTo 方法, 而必须实现 Comparable 接口呢? 主要原因在于 java 是一种强类型的语言;在调用方法的时候, 编译器将会检查这个方法是否存在, 如,
if(a[ i ].compareTo(a[ j ]) > 0)
{
............
}
编译器必须确认 a[i] 一定有 compareTo 方法,如果a 是一个 Comparable 对象 的数组, 就可以确保拥有 compareTo 方法,因为每个实现 Comparable 接口的类都必须提供这个方法的定义;
1.6)看个荔枝:
[API] java.lang.Comparable<T> 1.0
int compareTo(T other) :用这个对象域 与 other 进行比较;
[API] java.util.Arrays 1.2
static void sort(Object[] a) : 使用mergesort 对数组a中的元素进行排序; 要求数组中的元素必须实现了 Comparable 接口的类, 并且元素间必须是可
比较的;
[API] java.lang.Integer 7
static int compare(int x, int y) : 如果x<y 返回一个负数, 相等返回0, 否则返回一个正数;
Annotation)
出现的问题)因为 Manager 扩展了 Employee, 而 Employee实现的是Comparable , 而不是 Comparable, 如果 Manager覆盖了 compareTo, 就必须要有经理 与 雇员进行比较的心理准备, 决不能仅仅将 雇员转换为 经理;
class Manager extends Employee
{
public int compareTo(Employee other)
{
Manager otherManger = (Manager)other; //NO
......
}
}
解决办法(Solutions):
if(getClass != other.getClass()) throw new ClassCastException();
2.1)可以声明接口变量, 且接口变量必须引用实现了接口的类对象:
Comparable x ; 这是OK 的;
x = new Employee();
2.2)可以使用 instanceof 检查一个对象是否实现了某个特定的接口:
if(anObject instanceof Comparable) {}
2.3)接口也可以继承, 这里允许存在多条从具有较高通用性接口到较高专用性接口的链:看个荔枝
public interface Moveable {
void move(double x, double y);
}
//然后用 Movable 扩展一个 Powered 的接口:
public interface Powered extends Moveable {
double milesPerGallon();
}
//虽然在接口中不能包含实例域或静态方法, 但可以包含常量:
public interface Powered extends Moveable {
double milesPerGallon();
double SPEED_LIMIT = 95; // a public static final constant
}
2.4)类是单继承,但是可以实现多个接口;看个荔枝:
java 中有一个 非常重要的 内置接口, Cloneable, 如果某个类实现了这个Cloneable 接口,Object类中的 clone 方法就可以创建类对象的一个copy, 如果希望自己设计的类拥有 克隆和比较的能力, 只要实现这两个接口就可以了(一个类可实现多个接口);
class Employee implements Cloneable, Comparable
3.1)疑问?为什么java还要不辞辛苦引入接口概念? 为什么不将 Comparable直接设计成抽象类:
abstract class Comparable
{
public abstract int compareTo(Object obj);
}
//然后, Employee再扩展这个抽象类, 并提供 compareTo方法的实现:
class Employee extends Comprable
{
public int compareTo(Object other){ ... }
}
3.2)使用抽象类表示通用属性存在这样一个问题:每个类只能扩展一个类, 假设 Employee 类已经扩展了一个类, 比如Person, 它就不能再像下面这样扩展第二个类了; 但是每个类可以实现多个接口:
class Employee extends Person implements Comparble //OK