概念
接口,在 JAVA 编程语言中是一个引用类型,是抽象方法的集合,接口通常以 interface 来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口中只能包含抽象方法和全局常量。
接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
接口的声明语法格式如下:
[访问修饰符] interface 接口名称 [extends 其他的接口名] {
// 声明全局常量 (static final 变量)
// 抽象方法
}
接口有以下特性:
接口是隐式抽象的,当声明一个接口的时候,不必使用 abstract 关键字。
接口中每一个方法也是隐式抽象的,声明时同样不需要 abstract 关键字。
接口中的方法都是公有的(public),public 也可以省略。
接口的子类可以通过 implements 关键字实现多个接口。
接口的子类(如果不是抽象类)必须覆写接口中的全部抽象方法。
接口的对象可以利用子类对象的向上转型进行实例化赋值。
接口与类相似点:
一个接口可以有多个方法。
接口文件保存在 .java 结尾的文件中,文件名使用接口名。
接口的字节码文件保存在 .class 结尾的文件中。
接口相应的字节码文件必须在与包名称相匹配的目录结构中。
接口与类的区别:
接口不能用于实例化对象。
接口没有构造方法。
接口中所有的方法必须是抽象方法。
接口不能包含成员变量,除了全局常量 (static final 定义)。
接口不是被类继承了,而是要被类实现。
接口支持多继承,可以使用 extends 继承多个接口。
示例
interface A {
public void print();
}
interface B {
public void get();
}
class X implements A,B{
public void print(){
System.out.println(“A 接口的抽象方法 ”);
}
public void get(){
System.out.println(“B 接口的抽象方法 ”);
}
}
public class testDemo {
public static void main(String[] args) {
/* X x = new X();
A a = x; // 向上转型
B b = x; // 向上转型
b.get();
*/
A a = new X();
B b = (B)a;
b.get();
System.out.println(a instanceof A);
System.out.println(a instanceof B);
System.out.println(a instanceof X);
}
}
输出结果:
B 接口的抽象方法
true
true
true
总结:不要被引用变量所代表的类型所迷惑,而要看具体该引用变量所指向的实例对象(new 创建出来的类型)。
实际开发中接口的核心作用
定义不同层之间的操作标准,即定义一个标准。
表示一种操作能力,这种情况下,接口里可能不包含任何方法。
将服务端的远程方法暴露给客户端。
抽象类和接口的对比
抽象类和接口在使用形式上非常类似.
区别点
抽象类
接口
关键字
abstract class
interface
组成
构造方法、普通方法、抽象方法、static 方法、常量、变量
抽象方法、全局常量
子类使用
class 子类 extends 抽象类
class 子类 implement 接口 1, 接口 2,…
关系
抽象类可以实现多个接口
接口不能继承抽象类,可以继承多个父接口
权限
抽象类可以使用各种权限
接口只能使用 public
继承限制
单继承
多继承,子类可以实现多个接口
子类
子类都必须重写全部的抽象方法
同抽象类
实例化
无法直接实例化,依靠子类对象的向上转型进行对象的实例化
同抽象类
什么时候使用抽象类和接口
如果你拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类吧。
如果你想实现多重继承,那么你必须使用接口。由于 Java 不支持多继承,子类不能够继承多个类,但可以实现多个接口。因此你就可以使用接口来解决它。
如果基本功能在不断改变,那么就需要使用抽象类。如果不断改变基本功能并且使用接口,那么就需要改变所有实现了该接口的类。
当 extends 和 implement 同时使用时,extends 要放在前面。
Java8 中的默认方法和静态方法
Oracle 已经开始尝试向接口中引入普通方法和静态方法 (static),以此来减少抽象类和接口之间的差异。现在,我们可以为接口提供默认实现的方法了并且不用强制子类来实现它。
jdk1.8 允许在接口里面定义普通方法,但普通方法必须使用 default 修饰。