有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java不支持多重继承。有了接口,就可以得到多重继承的效果。
接口是抽象方法和常量值的定义的集合。
从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。
接口中的方法全是抽象方法,直接 new 接口来调用方法没有意义,Java也不允许这样干。
类与接口的关系为实现关系,即类实现接口。实现的动作类似继承,只是关键字不同,实现使用 implements。
其他类(实现类)实现接口后,就相当于声明: 我应该具备这个接口中的功能。实现类仍然需要重写方法以实现具体的功能。
格式:
class 类 implements 接口 { 重写接口中方法 }在类实现接口后,该类就会将接口中的抽象方法继承过来,此时该类需要重写该抽象方法,完成具体的逻辑。
示例:
/* * 接口的成员特点: * 只能有抽象方法(JDK 1.8之前) * 只能有常量 * 默认使用public abstract修饰方法 * 默认使用public static final来修饰成员变量 * * * 注意: * 接口不能创建对象(不能实例化) * 类与接口的关系是实现关系,一个类实现一个接口必须实现它所有的方法 * 子类必须覆盖掉接口中所有的抽象方法后,子类才可以实例化,否则子类是一个抽象类。 */ public class InterfaceDemo2 { public static void main(String[] args) { //Animal a = new Animal(); //Animal.num; } } interface Animal { public static final int num = 10; public abstract void eat(); } class Cat implements Animal { public void eat() { } }示例:
/* * * 类与类:继承关系,单一继承,多层继承 * 类与接口:实现关系,多实现 * 接口与接口的关系:继承关系,多继承 */ interface InterA extends InterB { public abstract void method(); } interface InterB { public abstract void function(); } interface InterC extends InterA { } class Demo implements InterC { @Override public void method() { // TODO Auto-generated method stub } @Override public void function() { // TODO Auto-generated method stub } }简单地说:接口的作用就是把使用接口的人和实现接口的人分开,实现接口的人不必要关心谁去使用,而使用接口的人也不用关心实现的细节。
重要性:在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制。正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力
简单、规范性:如果一个项目比较庞大,那么就需要一个能理清所有业务的架构师来定义一些主要的接口,这些接口不仅告诉开发人员你需要实现那些业务,而且也将命名规范限制住了(防止一些开发人员随便命名导致别的程序员无法看明白)
维护、拓展性:比如有一个类,实现了某个功能,突然有一天,发现这个类满足不了需求了,然后又要重新设计这个类,更糟糕是你可能要放弃这个类,那么其他地方可能有引用他,这样修改起来很麻烦
如果一开始定义一个接口,把功能放在接口里,然后定义类时实现这个接口,然后只要用这个接口去引用实现它的类就行了,以后要换的话只不过是引用另一个类而已,这样就达到维护、拓展的方便性。比如有个method1的方法,如果用接口,【接口名】 【对象名】=new 【实现接口的类】,这样想用哪个类的对象就可以new哪个对象了,new a();就是用a的方法,new b()就是用b的方法,就和USB接口一样,插什么读什么,就是这个原理
安全、严密性:接口是实现软件松耦合的重要手段,它描叙了系统对外的所有服务,而不涉及任何具体的实现细节。这样就比较安全、严密一些(一般软件服务商考虑的比较多,jdk中很多方法就是实现了某个接口)
实现递归排序算法
public class MergeSort implements IArraySort { @Override public int[] sort(int[] sourceArray) throws Exception { // 对 arr 进行拷贝,不改变参数内容 int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); if (arr.length < 2) { return arr; } int middle = (int) Math.floor(arr.length / 2); int[] left = Arrays.copyOfRange(arr, 0, middle); int[] right = Arrays.copyOfRange(arr, middle, arr.length); return merge(sort(left), sort(right)); } protected int[] merge(int[] left, int[] right) { int[] result = new int[left.length + right.length]; int i = 0; while (left.length > 0 && right.length > 0) { if (left[0] <= right[0]) { result[i++] = left[0]; left = Arrays.copyOfRange(left, 1, left.length); } else { result[i++] = right[0]; right = Arrays.copyOfRange(right, 1, right.length); } } while (left.length > 0) { result[i++] = left[0]; left = Arrays.copyOfRange(left, 1, left.length); } while (right.length > 0) { result[i++] = right[0]; right = Arrays.copyOfRange(right, 1, right.length); } return result; } }