一、接口基本概念
接口(interface):在java程序设计语言中,接口不是类,而是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义。通常用interface声明,接口就是抽象方法和全局变量的集合,一个类通过继承接口的方式从而来继承接口的抽象方法。
接口只有抽象方法和全局变量,构造方法也没有。
接口的定义:
1、定义接口使用关键字interface,为区分接口,接口的名称前面加I。
2、接口的数据成员默认为 public static final
接口的默认方法为public abstract
3、接口不能有自己的实现方法
范例:定义一个接口:
public interface IA { //定义一个接口,为了区分接口,建议在所以接口前面追加I
public static final String msg="Hello World";//定义全局常量
public abstract void fun1();//定义抽象方法
}
二、接口的使用
1、因为接口中含有抽象方法,所以接口对象不能用关键字new直接实例化,而是需要子类帮助实例化:
(1)接口必须要有子类,一个子类可以使用关键字implements关键字实现多个接口;
(2)接口的子类(非抽象类),必须实现接口中的所有抽象方法;
(3)接口的子类(抽象类),可以不实现接口的抽象方法;
(4)接口的对象可以通过向上转型进行实例化
范例:
interface IA { //定义一个接口,为了区分接口,建议在所以接口前面追加I
public static final String msg="Hello World";//定义全局常量
public abstract void fun1();//定义抽象方法
}
interface IB { //定于接口B
public abstract void fun2();
}
class Person implements IA,IB { //Person类实现了IA,IB两个接口
@Override
public void fun1() {
System.out.println("接口IA中的抽象方法fun1()");
}
@Override
public void fun2() {
System.out.println("接口IB中的抽象方法fun2()");
}
}
public class TestDemo6 {
public static void main(String[]args){
Person person=new Person(); //实例化子类对象
IA ia=person; //向上转型
IB ib=person; //向上转型
ia.fun1();
ib.fun2();
}
}
运行结果:
以上代码实例化了Person类的对象,由于Person类是IA,IB的子类,那么person对象可以变为IA,IB接口的对象,范例如下:
public class TestDemo6 {
public static void main(String[]args){
IA ia=new Person();
IB ib=(IB)ia;
ib.fun2();
}
}
运行结果:
验证:
public class TestDemo6 {
public static void main(String[]args){
IA ia=new Person();
IB ib=(IB)ia;
ib.fun2();
System.out.println(ia instanceof IA);
System.out.println(ia instanceof IB);
}
}
运行结果:
结论小陷阱:接口IA和IB没有任何直接关系,但是它们拥有同一个子类,这里不要被类型和名称误导,实例化的是X子类,这个对象既属于IA对象也属于IB对象,所以以上代码可行,但从代码规范和可读性上讲,并不推荐使用。
2、对于子类而言,除了实现接口外,还可以继承抽象类,如果要继承抽象类还要实现接口的话,使用以下语法格式:
class 子类[extends 父类][implements 接口1,接口2,...]{}
范例:
interface IA { //定义一个接口,为了区分接口,建议在所以接口前面追加I
public static final String msg="Hello World";//定义全局常量
public abstract void fun1();//定义抽象方法
}
interface IB { //定于接口B
public abstract void fun2();
}
abstract class C { //定义一个抽象类
public abstract void fun3();
}
class Person extends C implements IA,IB { //Person类实现了IA,IB两个接口
@Override
public void fun1() {
System.out.println("接口IA中的抽象方法fun1()");
}
@Override
public void fun2() {
System.out.println("接口IB中的抽象方法fun2()");
}
@Override
public void fun3() {
System.out.println("抽象类C的抽象方法fun3()");
}
}
由于接口中只有全局变量和抽象方法,为了书写方便,文章开头定义的接口其实可以等价于:
public interface IA { //定义一个接口,为了区分接口,建议在所以接口前面追加I
String msg="Hello World";//定义全局常量
void fun1();//定义抽象方法
}
但是这样做也会带来一定的影响:
范例:
interface IA{
String msg="Hello World";
void fun1();
}
class Person implements IA{
void fun1() {
System.out.println("接口IA的抽象方法fun1()");
}
}
public class TestDemo6{
public static void main(String[]args){
IA ia=new Person();
ia.fun1();
}
}
运行结果:
造成这样错误的原因:接口默认为public,若子类没有public修饰,则访问权限变严格了,给子类分配的是更低的访问权限,所以在实际开发时候建议在抽象方法前加上public,子类也加上。
interface IA{
String msg="Hello World";
public void fun1();
}
class Person implements IA{
public void fun1() {
System.out.println("接口IA中的抽象方法fun1()");
}
}
public class TestDemo6{
public static void main(String[]args){
IA ia=new Person();
ia.fun1();
}
}
3、一个抽象类只能继承一个抽象类,但一个接口却能通过关键字extends继承多个接口(但接口不能继承抽象类)
interface IA {
public void fun1();
}
interface IB {
public void fun2();
}
//IC接口同时继承IA,IB两个接口
interface C extends IA,IB {
public void fun3();
}
class Person implements C{
@Override
public void fun1() {
}
@Override
public void fun2() {
}
@Override
public void fun3() {
}
}
小结:从继承关系来说,接口的限制比抽象类少:
(1)一个抽象类只能继承一个父类,而接口可以继承多个接口;
(2)一个子类只能继承一个一个抽象类却能实现多个接口(接口解决了单继承的局限性);
4、接口只能由抽象类和全局变量组成,但内部结构不受限制
这个道理和抽象类中可以定义抽象内部类一样,接口中也可以定义普通内部类,抽象内部类,和内部接口(实际用户自己去定义内部抽象类和内部接口是比较少见的)
范例(定义一个抽象内部类):
interface IA {
public void fun1();
abstract class IB{//定义一个抽象内部类
public abstract void fun2();
}
}
接口中如果用static定义一个内部接口,它相当于一个外部接口:
范例:
interface IA {
public void fun1();
static interface IB{ //定义一个内部接口,用了static相当于一个外部接口
public void fun2();
}
}
class Person implements IA.IB{
@Override
public void fun2() {
}
}
三、接口的实际运用
接口在实际开发之中三大核心应用环境:
①定义操作标准(USB接口标准)
②表示能力
③在分布式开发之中暴露远程服务方法
范例:电脑上可以使用任何USB设备(U盘,打印机等)
现假设每一个USB 接口只能实现两个功能:①安装驱动 ②工作
(1)定义一个USB接口标准
public interface USB {
public void install();
public void work();
}
(2)定义电脑类(在电脑上应用此接口)
class Computer {
public void Plugin(USB usb) { //只能插USB设备
usb.install();
usb.work();
}
}
(3)定义USB设备—U盘
class UDisk implements USB{ //定义一个USB设备——U盘
@Override
public void install() {
System.out.println("安装U盘驱动");
}
@Override
public void work() {
System.out.println("U盘开始工作");
}
}
(4)定义USB设备—打印机
class Printer implements USB{ //定义一个USB设备——打印机
@Override
public void install() {
System.out.println("安装打印机驱动");
}
@Override
public void work() {
System.out.println("打印机开始工作");
}
}
(5)打印USB设备—手机
class Phone implements USB{ //定义一个USB设备——手机
@Override
public void install() {
System.out.println("安装手机驱动");
}
@Override
public void work() {
System.out.println("手机开始工作");
}
}
(6)测试类
public class TestDemo7 {
public static void main(String[]args){
Computer computer=new Computer();
computer.Plugin(new UDisk());
computer.Plugin(new Printer());
computer.Plugin(new Phone());
}
}
(7)运行结果: