接口快速入门
public class Test {
public static void main(String[] args) {
Phone phone = new Phone();
Camera camera = new Camera();
Computer computer = new Computer();
computer.work(phone);
computer.work(camera);
}
}
// 接口
interface UsbInterface{
public void start();
public void stop();
}
class Phone implements UsbInterface {
public void start(){
System.out.println("手机开始工作了....");
}
public void stop(){
System.out.println("手机停止工作了....");
}
}
class Camera implements UsbInterface {
public void start(){
System.out.println("相机开始工作了....");
}
public void stop(){
System.out.println("相机停止工作了....");
}
}
class Computer {
// 参数可以接收实现了 UsbInterface 接口的类的对象实例,体现了接口的多态参数
public void work(UsbInterface usbInterface){
// 调用接口中的方法
usbInterface.start();
usbInterface.stop();
}
}
基本介绍
接口就是给出一些没有实现的方法(抽象方法),封装到一起,当某个类要使用时,再根据具体情况实现这些方法
interface 接口名 {
// 属性
// 方法(抽象方法、默认实现方法、静态方法)
}
class 类名 implements 接口 {
自己属性;
自己方法;
必须实现接口的抽象方法
}
在 jdk7.0 前,接口里的所有方法都没有方法体,即都是抽象方法
jdk8.0 后接口可以有静态方法、默认方法,也就是说接口中可以有方法的具体实现
interface AInterface {
public int n1 = 10;
// 方法
// 在接口中,抽象方法可以省略 abstract 关键字
public void hi();
// jdk8 后,可以有默认(default)实现方法,需要用关键字 default 修饰
default public void ok(){
System.out.println("ok()....");
}
// jdk8 后,可以有静态方法
public static void cry(){
System.out.println("cry()....");
}
}
// 一个类实现一个接口,需要将该接口中的所有抽象方法实现
class A implements AInterface {
public void hi() {
System.out.println("hi()...");
}
}
接口的应用场景
- 比如要制造飞机、战斗机等,专家只需要制定飞机需要的功能/规格,而飞机的具体制造过程由别的人完成
- 开发一个软件,项目经理可以定义一些接口,然后由程序员具体实现
使用细节
- 接口不能被实例化,即不能 new
- 接口中的所有方法都是 public ,但可以省略 public,abstract 关键字也可以省略。如 void aaa(); 等价于 public abstract void aaa();
- 接口中的属性只能是 public static final 修饰符,比如 int a = 1; 实际上等价于 public static final int a = 1; (必须初始化)
- 接口中属性的访问:接口名.属性名 / 实现接口的类名.属性名 / 实现接口的类的对象实例.属性名
- 一个普通类实现接口,就必须将该接口的所有抽象方法实现
- 抽象类实现接口,可以不用实现接口的抽象方法,因为抽象类本身就允许有抽象方法的存在
- 一个类可以实现多个接口,接口之间以逗号分隔,但只能继承一个类
- 一个接口不能继承其他的类,但可以继承多个别的接口
interface A {}
interface B{}
class AA {}
interface C extends A,B {}
// interface D extends AA {} // 报错
- 接口的修饰符只能是 public 和默认,这和类的修饰符一样
接口 VS 继承
以猴子为例,比如猴子生下来就继承了祖辈的能力:爬树,但是猴子不会游泳、飞翔,但是猴子通过学习可以扩展游泳和飞翔这两个功能。
当子类继承了父类,就自动拥有了父类的功能,而如果子类需要扩展父类没有的功能,可以通过实现接口的方法进行扩展,可以理解为接口是对 java 单继承机制的一种补充
- 接口和继承解决的问题不同:继承的价值主要在于解决代码的复用性和可维护性,而接口的价值在于设计好各种规范(方法),让其他类去实现这些方法
- 接口比继承更加灵活:继承是满足 is-a 关系,接口是满足 is-like 关系
- 接口在一定程度上实现代码的解耦【接口规范性 + 动态绑定机制】
接口的多态特性
- 多态参数(如接口快速入门里的 Computer 类里的 work 方法的参数)
public class Test {
public static void main(String[] args) {
// 接口类型的变量,可以指向实现接口的类的对象实例
A a = new B();
}
}
interface A {}
class B implements A {}
- 多态数组(同前面所说的多态数组)
public class Test {
public static void main(String[] args) {
// 多态数组
A[] arr = new A[2];
arr[0] = new B();
arr[1] = new C();
}
}
interface A {}
class B implements A {}
class C implements A {}
- 接口存在多态传递现象
public class Test {
public static void main(String[] args) {
// 多态传递
IB ib = new BB();
/*
*
* 虽然 BB 没有直接实现 IA 接口,但 BB 实现了 IB 接口,并且 IB 接口继承了 IA 接口
* 所以实际上相当于 BB 类实现了 IA 接口
* 这称为接口多态传递
*/
IA ia = new BB();
}
}
interface IA {
void hi();
}
interface IB extends IA{}
class BB implements IB {
// 必须要实现 IA 接口中的抽象方法
public void hi(){}
}
小练习
interface A {
int x = 0;
}
class B {
int x = 1;
}
class C extends B implements A {
public void pX(){
// 报错,不能识别此处的 x 是谁,是 B 里的还是 A 里的
// System.out.println(x);
// 修改后
System.out.println(A.x); // 访问接口里的 x
System.out.println(super.x); // 访问父类里的 x
}
public static void main(String[] args) {
new C().pX();
}
}