Back

JavaInterface

接口的介绍与使用

JavaInterface


  1. 接口的基本介绍
  2. 接口的注意事项及使用细节
  3. 接口实现与类的继承
  4. 接口的多态性

接口基本介绍

  • 接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些方法写出来。

    接口的定义:

    interface 接口名{
        //属性
        //方法
    }
    

    类实现接口:

    class ClassName implements Interface {
        //自己的属性
        //自己的方法
        //必须实现的接口的抽象方法
    }
    
  • 在jdk7前,接口里的所以方法都没有方法体,即都是抽象方法。

  • jdk8后接口可以有静态方法,默认方法,也就是说接口中可以有方法的具体实现。但默认方法需要使用default关键字修饰

  • 在接口中,定义抽象方法时可以省略abstract关键字。如果一个类实现了接口,则需要把接口的所有抽象方法都实现。

    代码演示

    创建接口Interface01

    package com.interface_;
    
    public interface Interface01 {
        //定义属性
        public  int n =1;
        //定义抽象方法
        public void A();
        //定义默认方法
        default public void B(){
            System.out.println("我是默认方法");
        }
        //定义静态方法
        public static void C(){
            System.out.println("我是静态方法");
        }
    }
    

    创建实现类InterfaceImp01

    package com.interface_;
    
    public class InterfaceImp01 implements Interface01{
        @Override
        public void A() {
            System.out.println("实现抽象方法");
        }
    
        @Override
        public void B() {
            Interface01.super.B();
        }
    }
    

    创建测试类InterfaceTest

    package com.interface_;
    
    public class InterfaceTest {
        public static void main(String[] args) {
            InterfaceImp01 interfaceImp01 = new InterfaceImp01();
            interfaceImp01.A();
            interfaceImp01.B();
            //调用静态方法
            Interface01.C();
        }
    }
    

    输出结果:

    image01

  • 对于初学者来说,接口的概念不难理解。难的是不知道什么时候使用接口,下面例举应用场景来理解接口的使用:

    • 现在要制作战斗机,武装直升机。专家只需要把飞机需要的功能/规格定下来即可,然后让工程师来实现
    • 现在有一个项目经理,管理三个程序员,功能开发一个软件,为了控制和管理软件,项目经理可以定义一些接口,然后由程序员来实现。

接口的注意事项与使用细节

  • 接口不能被实例化

  • 接口中所有的方法都是public,接口中的抽象方法可以不用abstract修饰

    interface Interface{
        void say();
        //相当于
        public abstract void say();
    }
    
  • 一个普通类实现接口,就必须将该接口的所有方法都实现(可以使用alt+enter来解决)

  • 抽象类去实现接口时,可以不实现接口的抽象方法

  • 一个类可以同时实现多个接口。

    创建接口Interface01

    interface Interface01{
        say();
    }
    

    创建接口Interface02

    interface Interface02{
        hi();
    }
    

    实现类dog

    class dog implements Interface01,Interface02{
        @Override
        public void hi(){
    
        }
            @Override
        public void say(){
    
        }
    }
    
  • 接口中的属性只能是final,而且是public static final修饰符。属性的访问形式为接口名.属性名

    interface Interface01{
        int n = 1;
        //实际上是
        public static final int n = 1;//必须初始化值
    }
    

    证明:创建测试类InterfaceTest

    package com.interface_;
    
    public class InterfaceTest {
        public static void main(String[] args) {
          //此处可以直接调用接口Interface01的属性,证明该属性为static
            Interface01.n;
            Interface01.n = 10;//系统会报错,证明该属性被final修饰
        }
    }
    
  • 接口不能继承其他的类,但是可以继承其他接口。

    interface Interface03 extends Interface01,Interface02{
    
    }
    

    而且继承其他接口时不用实现其他接口的方法。

  • 接口的修饰符与类一样,只能是public或者是默认

  • 思考题:下面程序是否正确,正确的话输出什么?

    //创建接口
    public interface Interface02 {
        int a = 23;
    }
    //创建接口实现类
    public class InterfaceImp02 implements Interface02{
    
    }
    //创建测试类
    public class InterfaceTest {
        public static void main(String[] args) {
            InterfaceImp02 imp02 = new InterfaceImp02();
            System.out.println(imp02.a);
            //因为InterfaceImp02实现了接口Interface02 所以也可以成功输出
            System.out.println(InterfaceImp02.a);
            //a为static属性,所以可以输出
            System.out.println(Interface02.a);
        }
    }
    

    代码正确,输出结果为

    image02

接口实现与类继承

  • 当子类继承了父类,就会**自动的拥有父类的功能(方法)。**而如果子类需要拓展功能,可以通过实现接口的方式拓展

  • 可以理解成实现接口就是对Java单继承机制的一种补充

    下面举个例子理解接口实现与类继承

    例:假如有一只小猴子悟空,他继承了父亲的爬树技能。当他看到鱼儿在游泳时,就跟鱼儿学习了游泳技能;当他看到鸟儿在飞翔时,就跟鸟儿学习了飞翔技能…

    代码演示:

    创建猴子父类 Monkey

    package com.interface_;
    
    public class Monkey {
        private String name;
    
        public Monkey(String name) {
            this.name = name;
        }
        public void climbing(){
            System.out.println(name + "在爬树");
        }
    }
    

    子类LittleMonkey

    package com.interface_;
    
    public class LittleMonkey extends Monkey{
    
        public LittleMonkey(String name) {
            super(name);
        }
    }
    

    此时,LittleMonkey继承了Monkey,所以很自然的会爬树

    image03

    因为悟空需要拓展技能,我们创建接口FishAble和BirdAble

    package com.interface_;
    
    public interface FishAble {
        public void Swimming();
    }
    
    package com.interface_;
    
    public interface BirdAble {
        public void flying();
    }
    

    而且LittleMonkey也实现了FishAble与BirdAble

    package com.interface_;
    
    public class LittleMonkey extends Monkey implements BirdAble,FishAble{
    
        public LittleMonkey(String name) {
            super(name);
        }
    
        @Override
        public void flying() {
            System.out.println(this.getName()+"通过学习,学会了飞翔");
        }
    
        @Override
        public void Swimming() {
            System.out.println(this.getName()+"通过学习,学会了游泳");
        }
    }
    

    最终,悟空学会了飞翔与游泳

    public class InterfaceTest {
        public static void main(String[] args) {
            LittleMonkey wuKong = new LittleMonkey("悟空");
    
            wuKong.climbing();
            wuKong.flying();
            wuKong.Swimming();
        }
    }
    

    image04

  • 实现接口VS继承类

    接口和继承解决的问题不同

    • 继承的价值主要在于:解决代码的复用性和可维护性
    • 接口的价值主要在于:设计好各种规范(方法),让它的实现类去实现这些方法。更加的灵活

    接口比继承更加灵活

    • 继承是满足is-a的关系,而接口只需满足like-a的关系即可。

      比如:猫它是动物(is-a),而猫像鱼一样会游泳(like-a)

    接口在一定程度上实现代码解耦(即:接口的规范性+动态绑定机制)

接口的多态性

  • 接口类型的变量可以指向实现了接口类的对象实例

    package com.interface_;
    
    public class InterfacePolyParameter {
        public static void main(String[] args) {
            //接口的多态体现
            IF if01 = new Monster();
            if01 = new Car();
        }
    }
    interface IF{}
    class Monster implements IF{}
    class Car implements IF{}
    
    
  1. 多态参数的体现

    演示一个案例:有一个接口UsbInterface usb,既可以接收手机对象,又可以接收相机对象,就体现了接口的多态(接口引用可以指向实现了接口的类的对象)

    创建接口UsbInterface

    package com.interface_;
    
    public interface UsbInterface {
        void start();
        void stop();
    }
    

    创建接口实现类Phone1

    package com.interface_;
    
    public class Phone1 implements UsbInterface{
        @Override
        public void start() {
            System.out.println("Phone开始工作");
        }
    
        @Override
        public void stop() {
            System.out.println("Phone停止工作");
        }
    }
    

    创建接口实现类Camera1

    package com.interface_;
    
    public class Camera1 implements UsbInterface{
    
        @Override
        public void start() {
            System.out.println("Camera开始工作");
        }
    
        @Override
        public void stop() {
            System.out.println("Camera停止工作");
        }
    }
    

    创建类Computer01

    package com.interface_;
    
    public class Computer01 {
        //1. UsbInterface usbInterface 说明Work的形参类型是UsbInterface
        //2. 这个参数可以接收实现了UsbInterface接口的类的对象实例
        public void Work(UsbInterface usbInterface){
            usbInterface.start();
            usbInterface.stop();
        }
    }
    

    Tset

    package com.interface_;
    
    
    public class InterfaceTest02 {
        public static void main(String[] args) {
            //创建手机对象,Phone1实现了UsbInterface接口
            Phone1 phone1 = new Phone1();
            //创建相机对象,Camera1实现了UsbInterface接口
            Camera1 camera1= new Camera1();
            //创建计算机对象
            Computer01 computer01 = new Computer01();
    
            //把手机接入电脑
            computer01.Work(phone1);
            System.out.println("===============");
            //把相机接入电脑
            computer01.Work(camera1);
        }
    }
    

    运行结果

    image05

  2. 多态数组的体现

    演示一个案例:给定Usb数组中,存放Phone和Camera对象,Phone类还有一个特有的方法call(),请遍历Usb数组,如果是Phone对象,除了调用Usb接口定义的方法外,还需要调用Phone特有方法call。

    创建接口Usb

    interface Usb{
        void Work();
    }
    

    创建接口实现类Phone2与Camrea2

    class Phone2 implements Usb{
    
        @Override
        public void Work() {
            System.out.println("Phone工作了");
        }
        public void call(){
            System.out.println("Phone打电话");
        }
    }
    
    class Camera2 implements Usb{
    
        @Override
        public void Work() {
            System.out.println("Camera工作了");
        }
    }
    

    创建测试类InterfacePolyAry

    package com.interface_;
    
    public class InterfacePolyAry {
        public static void main(String[] args) {
            //多态数组 ->接口类型数组
            Usb[] usbs = new Usb[2];
            usbs[0] = new Phone2();
            usbs[1] = new Camera2();
            for (int i = 0; i<usbs.length; i++){
                usbs[i].Work();//多态绑定
                //需要进行类型的向下转型
                if(usbs[i] instanceof Phone2){
                    ((Phone2) usbs[i]).call();
                }
            }
        }
    }
    

    运行结果

    image06

  • 接口存在多态传递现象(代码演示)

    创建接口InterfacePoly1

    interface InterfacePoly1{
        void hi();
    }
    

    创建接口InterfacePoly2继承了接口创建接口InterfacePoly1

    interface InterfacePoly2 extends InterfacePoly1{
    
    }
    

    创建接口实现类InterfacePolyImp

    class InterfacePolyImp implements InterfacePoly2{
    
        @Override
        public void hi() {
            System.out.println("hi");
        }
    }
    

    创建测试类InterfacePolyPass

    package com.interface_;
    
    public class InterfacePolyPass {
        public static void main(String[] args) {
            //接口类型的变量可以指向实现了该接口的对象实例
            InterfacePoly2 interfacePoly2 = new InterfacePolyImp();
            //如果InterfacePoly2继承了InterfacePoly1接口,而InterfacePolyImp实现了InterfacePoly2接口
            //那么实际上就相当于InterfacePolyImp实现了InterfacePoly1接口
            //这就是所谓的接口多态传递现象
            InterfacePoly1 interfacePoly1 = new InterfacePolyImp();
    
        }
    }
    
Built with Hugo
Theme Stack designed by Jimmy