[05] 接口
1、接口的声明
接口是一系列抽象的集合,简单地说,它更像特殊的抽象类,类似所有方法都是抽象方法的抽象类。
当然,这只是简单地说法,还是稍有不同的:
- 抽象类可以有构造方法,接口没有构造方法
- 抽象类可以有成员变量,接口只能有常量
接口的声明不像抽象类使用 abstract class,而是使用新的关键字 interface:
【修饰符】 interface 接口名 【extends 父接口名列表】{
【public】【static】【final】常量;
【public】【abstract】方法;
}
4
1
【修饰符】 interface 接口名 【extends 父接口名列表】{
2
【public】【static】【final】常量;
3
【public】【abstract】方法;
4
}
- 修饰符只是为public,即不写,默认值也是public
- 接口可以继承父接口,且可以实现接口多继承(因为方法都是抽象方法)
- 方法只能有定义,没有实现
- 常量和方法的三个修饰符都可以省略
总结接口和抽象方法的区别就在于:
抽象类 | 接口 | |
属性 | 无限制 | 只能有静态常量 |
构造方法 | 可有可无 | 没有 |
普通方法 | 可以有具体实现的方法 | 必须是抽象方法 |
子类 | 单一继承 | 多重实现 |
2、类实现接口
子类和父类我们使用的是继承,而类和接口之间的关系我们使用的是“实现”,其本质和继承是相似的,区别在于,一个类只能继承一个父类,而一个类可以同时实现多个接口(多个接口用逗号隔开)。
实现接口采用 implements 关键字:
【访问权限修饰符】【修饰符】class 类名 implements 接口列表 {
类体
}
1
【访问权限修饰符】【修饰符】class 类名 implements 接口列表 {
2
类体
3
}
所以,接口实际上只是定义类要实现的操作,即“what to do”,而由类去实现接口,覆盖其中的方法,实现“how to do”。
3、接口的作用
多态!多态!多态!重要的事情说三遍!
接口最常用的,和我们在多态中提到过的一样,如果我们使用 “ 接口名 对象名 = new 实现接口的类 ”,就可以起到像USB插口一样的作用,插什么读什么,如果有接口定义了方法read,那么我们 new Map3(),就使用Map3的read;new Mp4(),就使用Mp4的read。
这叫做统一访问,为什么要像这样多此一举?
还是刚才的例子,假如我们电脑有某个插口用来传输多媒体文件,设定为只能读取Mp3,要把歌曲从电脑存进Mp3嘛,离线听才方便,可是后来突然不流行用Mp3听歌了,大家升级了用Mp4,没办法,为了顺应市场,你只能把这个插口改成读取Mp4,或许未来出现了MpN的话,你又得改这个接口。
这里的麻烦就在于,你的插口形状是去为了适应设备而不断更改,设备更换,插口也要更换;我们换个思路,将插口形状固定下来,让各种设备来匹配我们的插口,这样一来,你的插口就是接口,完全不用改变,而由设备去实现接口。
写代码的过程也是这样,程序员之间是相互协作的,程序员B调用了程序员A写的东西,程序员A只需要给B一个接口即可,让B去调用接口定义好的方法,假如因为需求的变化,程序员A也只需要修改接口实现类,而调用者B完全无需关心如何改变,B写的代码也不需要变动。这里程序员B就像是刚才例子里的电脑,调用的接口就像USB插口,各种设备就是程序员A针对接口写的各种实现。
再举个例子,就像我们项目中的业务层调用了持久层的方法,一般都是调用持久层接口的方式,假如我们业务类不是使用持久层接口,而是具体的持久层类,那么我数据库一旦有更改需求,业务层中的相应代码也需要全部变动。