接口
接口不是类,而是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义。
简单来说:如果类遵从某个特定接口,那么就履行这项义务。例如Arrays类中的sort方法承诺可以对对象数组进行排序,但要求满足的前提是实现Compareable接口:
public interface Compareable{
int compareTo(Object other);
}
这就是说任何实现CompareTo的接口的类都需要包含compareTo方法,并且这个方法的参数必须是Object对象,返回int类型值。
接口的方法不需加上public,默认自动属于public。此外接口中的域将会被自动设置为public static final为了让某个类实现一个接口通常需要两步:
- 将类声明为实现给定的接口。
- 对接口中的所有方法进行定义。
将类声明为实现某个接口时,需要使用关键字implements:
class Empolyee implements Comparable
要让一个类实现排序服务就必须实现compareTo的方法,但为什么不能直接在Employee中定义,而需要在接口中声明呢?
java是一种强类型
语言,在调用方法时编译器会检查这个方法是否存在。在sort方法中可能存在以下的语句:
if(a[i].compareTo(a[j]>0))
{
//rerrange a[i] and a[j];
}
为此编译器一定要存在compareTo的方法,为了保证一定有compareTo的方法因而Employee要实现接口方法的定义,在此声明接口。
接口特性
接口不是类,不能使用new运算符实例化一个接口,然而却可以声明接口的变量:Compare x;接口变量必须引用实现了接口的类对象。x=new Employee(….);
如同建立类的继承关系一样,接口也可以被扩展。这里允许存在多条从具有讲稿通用性的接口到较高专用性的接口的链。
接口与抽象类
接口与抽象类有诸多相同的特征,但又有所不同。
抽象类在表示通用属性时存在一个问题:每个类只能拓展与一个类,然而每个类却可以实现多个接口。
class Employee extends Person
class Employee implements Person,Man
可以为接口方法定义一个默认实现,必须用default修饰标记这样一个方法。
例如:
public interface Collection
{
int size();
default boolean isEmpty()
{
return size()==0;
}
}
如果在default方法中实现了size()==0程序员就无需在后面担心isEmpty()方法了。
解决默认冲突
如果先在一个接口中将一个方法定义为默认方法,然后又在超类或另一个接口中定义了同样的·方法。规则如下:
- 超类优先:如果超类提供了一个具体方法,同名而且具有相同的参数类型的默认方法会被忽略(子类被忽略)。
- 接口冲突:如果一个超接口提供了一个默认方法,另一个接口提供了一个同名且参数类型相同的方法,必须覆盖这个方法来解决冲突。
冲突二:
interface Named{
default String getName(){
return getClass().getName();
}
class Student implements Person ,Named
{
}
}
解决方法:覆盖:
class Student implements Person,Named{
public String getName(){
return Person.super.getName();
}
}
如果只在Person中定义了同名方法,Named和Person的冲突仍存在而已性,必须实现。
而对于继承超类中的接口方法无论如何都是超类优先。