• Java接口


    1. 什么是接口?
      在Java中,接口可以看成是多个类的公共规范,是一种引用数据类型。

    2. 使用关键字interface来定义接口

    interface IRunning {
        void run();
    }
    
    • 1
    • 2
    • 3

    在创建接口时,接口的命名一般以大写字母I开头,接口的命名一般使用形容词词性的单词。【阿里编码规范中约定,接口中的方法和属性不要加任何修饰符号,保持代码的简洁性。】

    1. 接口不能被实例化
      在这里插入图片描述

    2. 接口当中的成员默认是public static final (静态常量)

        public String name = "小王";
        public static String name2 = "小王";
        public static final String name3 = "小王";
    
    • 1
    • 2
    • 3

    name为斜体,因为一个变量如果被static修饰,则变量名就变成斜体了,而且静态常量必须赋初始值,否则会报错。

    1. 接口当中的方法不写也是默认为public abstract,而且只能是public abstract,其他修饰符都会报错在这里插入图片描述
    2. 接口当中的方法不能由具体的实现,但是从jdk8开始可以写一个default修饰的具体实现的方法
      在这里插入图片描述
    3. 接口当中不能有构造方法,因为成员变量都是static final的,所有定义的变量一定是已经赋值的。
      在这里插入图片描述
    4. 接口需要被类实现,使用关键字implements
    interface IRunning {
        void run();
    }
    
    public class Test implements IRunning {
        @Override
        public void run() {
            System.out.println("实现接口中的run方法");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. 接口当中可以有static修饰的方法
    interface IRunning {
        void run();
        public static void func() {
            System.out.println("接口中static方法");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    总结:接口中可以有3种方法,2种比较特殊(default修饰的方法,static修饰的方法)

    1. 接口不能直接使用,必须要有一个“实现类”,实现接口中的所有抽象方法
      【注意:子类和父类之间是extends继承关系,类和接口之间是implements实现关系】

    2. 实现笔记本电脑使用USB鼠标、USB键盘的例子
      ①USB接口:包含打开设备、关闭设备功能
      ②鼠标类:实现USB接口,并具备点击功能
      ③键盘类:实现USB接口,并具备输入功能
      ④笔记本类:包含开机功能、关机功能,使用USB设备功能

    package demo;
    //Usb接口:包含打开设备、关闭设备功能
    public interface IUSB {
        void openDevice();
        void closeDevice();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    package demo;
    
    public class KeyBoard implements IUSB{
        @Override
        public void openDevice() {
            System.out.println("打开键盘");
        }
    
        @Override
        public void closeDevice() {
            System.out.println("关闭键盘");
        }
    
        public void inPut(){
            System.out.println("键盘输入");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    package demo;
    
    public class Mouse implements IUSB{
        @Override
        public void openDevice() {
            System.out.println("打开鼠标");
        }
    
        @Override
        public void closeDevice() {
            System.out.println("关闭鼠标");
        }
    
        public void click() {
            System.out.println("鼠标点击");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    package demo;
    
    public class Computer {
        public void open() {
            System.out.println("打开电脑");
        }
    
        public void close() {
            System.out.println("关闭电脑");
        }
    
        public void func(IUSB iusb) {
            iusb.openDevice();
            if (iusb instanceof KeyBoard) {
                ((KeyBoard) iusb).inPut();
            }else if (iusb instanceof Mouse) {
                ((Mouse) iusb).click();
            }
            iusb.closeDevice();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    package demo;
    
    public class Test {
        public static void main(String[] args) {
            Computer computer = new Computer();
            computer.func(new Mouse());
            System.out.println("=========");
            computer.func(new KeyBoard());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    运行结果:
    在这里插入图片描述
    分析:在func方法中,发生了向上转型,传入的是接口类型,站在这个角度,我们就可以不关心usb这个引用到底引用了哪个对象,只要实现了这个接口的规范就可以传进来。
    动态绑定和多态:从代码的角度,可以省略代码,而且还融入了设计的思想。

    1. 重写接口中方法时,不能使用默认的访问权限
      因为子类重写方法的权限要大于等于父类,接口(父类)中方法都是public abstract的,所以子类重写的权限只能时public的
      在这里插入图片描述
    2. 实现多个接口
      在java中,类和类之间是单继承的,一个类只能有一个父类【不支持多继承】,但是在Java中一个类可以实现多个接口
      例子:结合抽象类和接口实现动物类,狗类,鱼类,鸭类等。
      整体代码:定义跑、游、飞的接口;定义动物类,狗类,鱼类,鸭类;并在Test类当中测试。
      在上述基础上,定义机器人类【有了接口之后,类的使用者就不必关注具体类型,让程序员忘记类型】,机器人类实现跑的接口,因此实例化机器人对象可以调用walk1方法,即使机器人不是动物类。

    接口:会跑的、会游的、会飞的

    package demo1;
    
    public interface IRunning {
        void run();
    }
    
    package demo1;
    
    public interface ISwimming {
        void swim();
    }
    
    
    package demo1;
    
    public interface IFly {
        void fly();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    动物类:设计被抽象类

    package demo1;
    
    public abstract class Animal {
        public String name;
    
        public Animal(String name) {
            this.name = name;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    狗类:狗是一个动物,具备running这样的一个功能

    package demo1;
    
    public class Dog extends Animal implements IRunning{
        @Override
        public void run() {
            System.out.println(name + "用四条狗腿在跑");
        }
    
        public Dog(String name){
            super(name);
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    鱼类:鱼是一个动物,具备swimming这样的一个功能

    package demo1;
    
    public class Fish extends Animal implements ISwimming{
        @Override
        public void swim() {
            System.out.println(name + "在水里游游游");
        }
    
        public Fish(String name) {
            super(name);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    鸭类:鸭是一个动物,具备running、swimming以及flying3个功能【实现多个接口】

    package demo1;
    
    public class Duck extends Animal implements IRunning, ISwimming, IFly{
        @Override
        public void fly() {
            System.out.println(name + "在天上飞飞飞");
        }
    
        @Override
        public void run() {
            System.out.println(name + "在地上跑跑跑");
        }
    
        @Override
        public void swim() {
            System.out.println(name + "在水里游游游");
        }
    
        public Duck(String name) {
            super(name);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    机器人类:机器人有running这样的功能,但是机器人不是动物类。【因为接口让程序员忘记类型】

    package demo1;
    
    public class Robat implements IRunning{
        private String name;
        @Override
        public void run() {
            System.out.println(name + "用机器腿在跑");
        }
    
        public Robat(String name) {
            this.name = name;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    测试类:

    package demo1;
    
    public class Test {
    
        public static void walk1(IRunning iRunning) {
            iRunning.run();
        }
    
        public static void walk2(ISwimming iSwimming) {
            iSwimming.swim();
        }
    
        public static void walk3(IFly iFly) {
            iFly.fly();
        }
    
    
    
        public static void main(String[] args) {
            Dog dog = new Dog("旺财");
            walk1(dog);
            System.out.println("===========");
            Fish fish = new Fish("小鱼儿");
            walk2(fish);
            System.out.println("===========");
            Duck duck = new Duck("唐老鸭");
            walk1(duck);
            walk2(duck);
            walk3(duck);
            System.out.println("===========");
            Robat robat = new Robat("小王");
            walk1(robat);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    运行结果:
    在这里插入图片描述
    分析:在walk方法内部,我们并不关注到底是哪种动物,只要参数是会跑的就行,甚至参数可以不是“动物”,比如机器人,只要会跑,总而言之接口让我们忘记了类型,只要实现了这个接口就可以传。

    1. 接口之间的继承
      在Java中,类和类之间是单继承的,但是一个类可以实现多个接口,并且接口和接口之间可以多继承【接口的扩展】。
    package demo1;
    
    public interface IRunAndSwim extends IRunning, ISwimming{
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    此时如果类要实现 IRunAndSwim 接口,则不仅要实现run方法,也要是心啊swim方法。
    接口间的继承相当于把多个接口合并在一起。

    1. 总结
      类可以继承一个普通类
      类可以继承一个抽象类
      类可以继承一个普通类/抽象类,同时实现多个接口
      接口可以扩展多个接口
  • 相关阅读:
    新鲜速递:Spring Cloud Alibaba环境在Spring Boot 3时代的快速搭建
    java多线程之概念和3种创建方式(详解)
    如何在外部数据库中存储空间化表时使用Mapinfo_mapcatalog
    全球唯一互帮互助平台——HowHelp,简直太赞了
    Apollo安装
    Android源码下载
    InfluxDB 内存消耗分析及性能优化
    Spring Boot自动装配原理和源码分析
    读完 RocketMQ 源码,我学会了如何优雅的创建线程
    Docker 仓库与注册表: 构建可靠的容器镜像生态系统
  • 原文地址:https://blog.csdn.net/weixin_44070116/article/details/127909874