一、接口基本概念

接口(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();

    }
}

运行结果:

java hessian 接口 java接口详解_java

以上代码实例化了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();

    }
}

运行结果:

java hessian 接口 java接口详解_接口的使用_02

验证:

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);

    }
}

运行结果:

java hessian 接口 java接口详解_接口_03

结论小陷阱:接口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();
    }
}

运行结果:

java hessian 接口 java接口详解_java接口_04

造成这样错误的原因:接口默认为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盘,打印机等)

java hessian 接口 java接口详解_java_05

现假设每一个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)运行结果:

java hessian 接口 java接口详解_java_06