【Java】—— Java面向对象高级:接口(interface)

目录

7. 接口(interface)

7.1 类比

7.2 概述

7.3 定义格式

7.3.1 接口的声明格式

7.3.2 接口的成员说明

7.4 接口的使用规则

练习1:

练习2:交通工具案例


7. 接口(interface)

7.1 类比

        生活中大家每天都在用USB接口,那么USB接口与我们今天要学习的接口有什么相同点呢?

        USB,(Universal Serial Bus,通用串行总线)是Intel公司开发的总线架构,使得在计算机上添加串行设备(鼠标、键盘、打印机、扫描仪、摄像头、充电器、MP3机、手机、数码相机、移动硬盘等)非常容易。

        其实,不管是电脑上的USB插口,还是其他设备上的USB插口都只是遵循了USB规范的一种具体设备而已。

        只要设备遵循USB规范的,那么就可以与电脑互联,并正常通信。至于这个设备、电脑是哪个厂家制造的,内部是如何实现的,我们都无需关心。

        Java的软件系统会有很多模块组成,那么各个模块之间也应该采用这种面向接口低耦合,为系统提供更好的可扩展性和可维护性。

7.2 概述

        接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/要...则必须能...”的思想。继承是一个"是不是"的is-a关系,而接口实现则是 "能不能"的has-a关系。

  • 例如:电脑都预留了可以插入USB设备的USB接口,USB接口具备基本的数据传输的开启功能和关闭功能。你能不能用USB进行连接,或是否具备USB通信功能,就看你能否遵循USB接口规范

        

  • 例如:Java程序是否能够连接使用某种数据库产品,那么要看该数据库产品能否实现Java设计的JDBC规范

接口的本质是契约、标准、规范,就像我们的法律一样。制定好后大家都要遵守。

7.3 定义格式

        接口的定义,它与定义类方式相似,但是使用 interface 关键字。它也会被编译成.class文件,但一定要明确它并不是类,而是另外一种引用数据类型。

引用数据类型:数组,类,枚举,接口,注解。

7.3.1 接口的声明格式

[修饰符] interface 接口名{
    //接口的成员列表:
    // 公共的静态常量
    // 公共的抽象方法
    
    // 公共的默认方法(JDK1.8以上)
    // 公共的静态方法(JDK1.8以上)
    // 私有方法(JDK1.9以上)
}

示例代码:

public interface USB3{
    //静态常量
    long MAX_SPEED = 500*1024*1024;//500MB/s

    //抽象方法
    void in();
    void out();

    //默认方法
    default void start(){
        System.out.println("开始");
    }
    default void stop(){
        System.out.println("结束");
    }

    //静态方法
    static void show(){
        System.out.println("USB 3.0可以同步全速地进行读写操作");
    }
}

7.3.2 接口的成员说明

在JDK8.0 之前,接口中只允许出现:

(1)公共的静态的常量:其中public static final可以省略

(2)公共的抽象的方法:其中public abstract可以省略

理解:接口是从多个相似类中抽象出来的规范,不需要提供具体实现

在JDK8.0 时,接口中允许声明默认方法静态方法

(3)公共的默认的方法:其中public 可以省略,建议保留,但是default不能省略

(4)公共的静态的方法:其中public 可以省略,建议保留,但是static不能省略

在JDK9.0 时,接口又增加了:

(5)私有方法

除此之外,接口中没有构造器,没有初始化块,因为接口中没有成员变量需要动态初始化。

7.4 接口的使用规则

1、类实现接口(implements)

        接口不能创建对象,但是可以被类实现(implements ,类似于被继承)。

        类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类。实现的动作类似继承,格式相仿,只是关键字不同,实现使用 implements关键字。

【修饰符】 class 实现类  implements 接口{
    // 重写接口中抽象方法【必须】,当然如果实现类是抽象类,那么可以不重写
      // 重写接口中默认方法【可选】
}

【修饰符】 class 实现类 extends 父类 implements 接口{
    // 重写接口中抽象方法【必须】,当然如果实现类是抽象类,那么可以不重写
      // 重写接口中默认方法【可选】
}

注意:

  1. 如果接口的实现类是非抽象类,那么必须重写接口中所有抽象方法

  2. 默认方法可以选择保留,也可以重写。

    重写时,default单词就不要再写了,它只用于在接口中表示默认方法,到类中就没有默认方法的概念了

  3. 接口中的静态方法不能被继承也不能被重写

2、接口的多实现(implements)

        之前学过,在继承体系中,一个类只能继承一个父类。而对于接口而言,一个类是可以实现多个接口的,这叫做接口的多实现。并且,一个类能继承一个父类,同时实现多个接口。

实现格式

【修饰符】 class 实现类  implements 接口1,接口2,接口3。。。{
    // 重写接口中所有抽象方法【必须】,当然如果实现类是抽象类,那么可以不重写
      // 重写接口中默认方法【可选】
}

【修饰符】 class 实现类 extends 父类 implements 接口1,接口2,接口3。。。{
    // 重写接口中所有抽象方法【必须】,当然如果实现类是抽象类,那么可以不重写
      // 重写接口中默认方法【可选】
}

接口中,有多个抽象方法时,实现类必须重写所有抽象方法。如果抽象方法有重名的,只需要重写一次

举例:

3、接口的多继承(extends)

        一个接口能继承另一个或者多个接口,接口的继承也使用 extends 关键字,子接口继承父接口的方法。

所有父接口的抽象方法都有重写。

方法签名相同的抽象方法只需要实现一次。

4、接口与实现类对象构成多态引用

        实现类实现接口,类似于子类继承父类,因此,接口类型的变量与实现类的对象之间,也可以构成多态引用。通过接口类型的变量调用方法,最终执行的是你new的实现类对象实现的方法体。

5、使用接口的静态成员

        接口不能直接创建对象,但是可以通过接口名直接调用接口的静态方法和静态常量。

6、使用接口的非静态方法

  • 对于接口的静态方法,直接使用“接口名.”进行调用即可

    • 也只能使用“接口名."进行调用,不能通过实现类的对象进行调用

  • 对于接口的抽象方法、默认方法,只能通过实现类对象才可以调用

    • 接口不能直接创建对象,只能创建实现类的对象

练习1:

CompareObject.java
package exer5;

/**
 * ClassName:IntelliJ IDEA
 * Description:
 *      定义一个接口用来实现两个对象的比较。
 * @Author zyjstart
 * @Create:2024/9/12 23:28
 */
public interface CompareObject {
    //若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小
    public int compareTo(Object o);
}

Circle.java

package exer5;

/**
 * ClassName:IntelliJ IDEA
 * Description:
 *      定义一个Circle类,声明redius属性,提供getter和setter方法
 * @Author zyjstart
 * @Create:2024/9/12 23:29
 */
public class Circle {
    private double radius;  // 半径

    public Circle() {
    }

    public Circle(double radius) {
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    @Override
    public String toString() {
        return "Circle{" +
                "radius=" + radius +
                '}';
    }
}
ComparableCircle.java
package exer5;

/**
 * ClassName:IntelliJ IDEA
 * Description:
 *      定义一个ComparableCircle类,继承Circle类并且实现CompareObject接口。
 *      在ComparableCircle类中给出接口中方法compareTo的实现体,用来比较两个圆的半径大小。
 * @Author zyjstart
 * @Create:2024/9/12 23:32
 */
public class ComparableCircle extends Circle implements CompareObject{

    public ComparableCircle() {
    }

    public ComparableCircle(double radius) {
        super(radius);
    }

    // 根据对象的半径的大小,比较对象的大小
    @Override
    public int compareTo(Object o) {
        if(this == o){
            return 0;
        }
        // 正确的写法1:
        if (o instanceof CompareObject){
            ComparableCircle c = (ComparableCircle) o;

            // 正确的写法1:
            /*
            if (this.getRadius() > c.getRadius()){
                return 1;
            }else if (this.getRadius() < c.getRadius()){
                return -1;
            }else {
                return 0;
            }*/

            // 正确的写法2:
            return Double.compare(this.getRadius(),c.getRadius());
        }else {
            throw new RuntimeException("输入的类型不匹配");
        }

    }
}
InterfaceTest.java
package exer5;

/**
 * ClassName:IntelliJ IDEA
 * Description:
 *      定义一个测试类InterfaceTest,创建两个ComparableCircle对象,调用compareTo方法比较两个类的半径大小。
 * @Author zyjstart
 * @Create:2024/9/12 23:47
 */
public class InterfaceTest {
    public static void main(String[] args) {
        ComparableCircle c1 = new ComparableCircle(2.3);
        ComparableCircle c2 = new ComparableCircle(5.3);

        int i = c1.compareTo(c2);

        if (i > 0){
            System.out.println("c1对象大");
        }else if (i < 0){
            System.out.println("c2对象大");
        }else {
            System.out.println("c1和c2一样大");
        }

    }
}


练习2:交通工具案例

阿里的一个工程师,声明的属性和方法如下:

        其中,有一个乘坐交通工具的方法takingVehicle(),在此方法中调用交通工具的run()。为了出行方便,他买了一辆捷安特自行车、一辆雅迪电动车和一辆奔驰轿车。这里涉及到的相关类及接口关系如下:

其中,电动车增加动力的方式是充电,轿车增加动力的方式是加油。在具体交通工具的run()中调用其所在类的相关属性信息。

请编写相关代码,并测试。

提示:创建Vehicle[]数组,保存阿里工程师的三辆交通工具,并分别在工程师的takingVehicle()中调用。

Vechicle.java

package exer6;

/**
 * ClassName:IntelliJ IDEA
 * Description:
 *      车辆类
 * @Author zyjstart
 * @Create:2024/9/13 15:02
 */
public abstract class Vehicle {
    private String brand;   // 品牌
    private String color;   // 颜色

    public Vehicle() {
    }

    public Vehicle(String brand, String color) {
        this.brand = brand;
        this.color = color;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public abstract void run();
}

IPowe.java

package exer6;

/**
 * ClassName:IntelliJ IDEA
 * Description:
 *
 * @Author zyjstart
 * @Create:2024/9/13 15:19
 */
public interface IPower {
    void power();
}
Vehicle.java
package exer6;

/**
 * ClassName:IntelliJ IDEA
 * Description:
 *      车辆类
 * @Author zyjstart
 * @Create:2024/9/13 15:02
 */
public abstract class Vehicle {
    private String brand;   // 品牌
    private String color;   // 颜色

    public Vehicle() {
    }

    public Vehicle(String brand, String color) {
        this.brand = brand;
        this.color = color;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public abstract void run();
}
ElectricVehicle.java
package exer6;

/**
 * ClassName:IntelliJ IDEA
 * Description:
 *      电动车类
 * @Author zyjstart
 * @Create:2024/9/13 15:10
 */
public class ElectricVehicle extends Vehicle implements IPower{


    public ElectricVehicle() {
    }

    public ElectricVehicle(String brand, String color) {
        super(brand, color);
    }

    @Override
    public void run() {
        System.out.println("电动车通过电机驱动行驶!");
    }

    @Override
    public void power() {
        System.out.println("电动车使用电力提供动力");
    }
}
Bicycle.java
package exer6;

/**
 * ClassName:IntelliJ IDEA
 * Description:
 *      自行车类
 * @Author zyjstart
 * @Create:2024/9/13 15:06
 */
public class Bicycle extends Vehicle{

    public Bicycle() {
    }

    public Bicycle(String brand, String color) {
        super(brand, color);
    }

    @Override
    public void run() {
        System.out.println("自行车通过脚踩行驶");
    }
}
VechicleTest.java
package exer6;

/**
 * ClassName:IntelliJ IDEA
 * Description:
 *      测试类
 * @Author zyjstart
 * @Create:2024/9/13 15:22
 */
public class VechicleTest {
    public static void main(String[] args) {
        Developer developer = new Developer();

        // 创建三个交通工具,保存在数组中
        Vehicle[] vehicles = new Vehicle[3];
        vehicles[0] = new Bicycle("宝如马","白色");
        vehicles[1] = new ElectricVehicle("爱玛","黄色");
        vehicles[2] = new Car("雅迪","黑色","粤C12345");

        for (int i = 0; i < vehicles.length; i++) {
            developer.takingVechicle(vehicles[i]);

            if (vehicles[i] instanceof IPower){
                ((IPower) vehicles[i]).power();
            }
        }
    }
}

运行如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值