【Java】接口interface学习

参考资料::黑马程序员·入门到飞起上

1 概述

在学习完抽象类后,我们了解到抽象类中既可以包含抽象方法,也能有普通方法、构造方法以及成员变量等。而接口则是一种更为彻底的抽象形式。在JDK7及之前的版本中,接口内全部为抽象方法,并且接口同样无法创建对象。

在Java中,接口(Interface)在JDK 7之前和之后(主要是JDK 8及更高版本)有显著的区别,主要体现在功能扩展上。以下是主要差异:

2 JDK7和它之后版本的区别

特性 JDK 7及之前 JDK 8及之后
抽象方法 仅支持 支持
默认方法 不支持 支持(default
静态方法 不支持 支持
私有方法 不支持 JDK 9+支持
常量字段 支持 支持
函数式接口 无明确支持 支持(@FunctionalInterface

3 接口成分的特点

在JDK7及之前,接口主要包含抽象方法和常量。

3.1抽象方法

需要注意的是,接口中的抽象方法默认会自动添加public abstract修饰,程序员无需手动书写。按照规范,日后在接口中定义抽象方法时,建议省略public abstract,因为系统会自动添加。

3.2 常量

在接口中定义的成员变量,默认会被public static final修饰。这意味着接口中定义的成员变量实际上是常量。经public static final修饰后,变量值不可修改,且由于其静态化特性,可直接通过接口名访问,因此称为常量。常量命名规范建议全部字母大写,多个单词间用下划线连接。

3.3 案例演示

以下通过具体代码示例展示接口的定义:

java 复制代码
public interface InterF {
    // 抽象方法!
    //    public abstract void run();
    void run();

    //    public abstract String getName();
    String getName();

    //    public abstract int add(int a, int b);
    int add(int a, int b);


    // 它的最终写法是:
    // public static final int AGE = 12 ;
    int AGE = 12; //常量
    String SCHOOL_NAME = "黑马程序员";
}

4 基本的实现

4.1 实现接口的概述

在Java中,类与接口之间存在实现关系,即类实现接口。实现接口的类被称为接口的实现类,也可称作接口的子类。实现的操作类似于继承,格式相似,只是使用的关键字不同,实现使用implements关键字。

4.2 实现接口的格式

接口实现的格式如下:

java 复制代码
/**接口的实现:
    在Java中接口是被实现的,实现接口的类称为实现类。
    实现类的格式:*/
class 类名 implements 接口1,接口2,接口3...{

}

从上述格式可以看出,一个类可以实现多个接口,即接口支持多实现。这是因为接口代表一种规范,一个类可以遵循多种不同的规范,以满足不同方面的功能需求。

4.3 类实现接口的要求和意义

  1. 实现类必须重写其所实现的全部接口中的所有抽象方法。
  2. 如果一个类实现了接口,但未重写全部接口的所有抽象方法,那么这个类必须被定义为抽象类。
  3. 意义:接口体现的是一种规范,它对实现类具有强制性的约束。实现类要么完整实现接口所声明的功能,要么自身定义为抽象类。这种强制性规范确保了程序的一致性和规范性,不同的实现类按照统一的接口规范实现特定功能,便于代码的组织和维护。

情况 1:普通类不实现全部方法(❌ 编译错误)

java 复制代码
interface Animal {
    void eat();
    void sleep();
}

class Dog implements Animal {  // ❌ 编译错误:必须实现所有接口方法
    @Override
    public void eat() {
        System.out.println("Dog is eating.");
    }
    // 缺少 sleep() 的实现
}

错误信息:

复制代码
Error: Dog is not abstract and does not override abstract method sleep() in Animal

情况 2:抽象类不实现全部方法(✔️ 合法)

如果类声明为 abstract,则可以 不实现接口的部分或全部方法,但子类仍需实现剩余方法。

java 复制代码
interface Animal {
    void eat();
    void sleep();
}

abstract class AbstractDog implements Animal {  // ✔️ 合法:抽象类可以不实现接口方法
    @Override
    public void eat() {
        System.out.println("AbstractDog is eating.");
    }
    // 未实现 sleep(),由子类完成
}

class RealDog extends AbstractDog {  // 子类必须实现剩余的 sleep()
    @Override
    public void sleep() {
        System.out.println("RealDog is sleeping.");
    }
}

情况 3:接口有默认方法(Java 8+ ✔️ 合法)

如果接口方法有 default 实现,实现类可以 选择不重写

java 复制代码
interface Animal {
    void eat();
    default void sleep() {  // 提供默认实现
        System.out.println("Animal is sleeping.");
    }
}

class Dog implements Animal {  // ✔️ 合法:只需实现 eat()
    @Override
    public void eat() {
        System.out.println("Dog is eating.");
    }
    // 不重写 sleep(),直接使用接口的默认实现
}

调用:

java 复制代码
Dog dog = new Dog();
dog.eat();   // 输出: Dog is eating.
dog.sleep(); // 输出: Animal is sleeping. (使用默认方法)

场景 是否合法 说明
普通类不实现全部方法 编译错误,必须实现所有抽象方法
抽象类不实现全部方法 ✔️ 剩余方法由子类实现
接口有 default 方法 ✔️ 可选择性重写

4.4 类与接口基本实现案例

以定义一个运动员的接口(规范)为例,代码如下:

java 复制代码
/**
   接口:接口体现的是规范。
 * */
public interface SportMan {
    void run(); // 抽象方法,跑步。
    void law(); // 抽象方法,遵守法律。
    String compittion(String project);  // 抽象方法,比赛。
}

接下来定义一个乒乓球运动员类作为接口的实现类,代码如下:

java 复制代码
package com.itheima;
/**
 * 接口的实现:
 *    在Java中接口是被实现的,实现接口的类称为实现类。
 *    实现类的格式:
 *      class 类名 implements 接口1,接口2,接口3...{
 *
 *
 *      }
 * */
public class PingPongMan implements SportMan {
    @Override
    public void run() {
        System.out.println("乒乓球运动员稍微跑一下!!");
    }

    @Override
    public void law() {
        System.out.println("乒乓球运动员守法!");
    }

    @Override
    public String compittion(String project) {
        return "参加" + project + "得金牌!";
    }
}

以下是测试代码:

java 复制代码
public class TestMain {
    public static void main(String[] args) {
        // 创建实现类对象。
        PingPongMan zjk = new PingPongMan();
        zjk.run();
        zjk.law();
        System.out.println(zjk.compittion("全球乒乓球比赛"));
    }
}

4.5 类与接口的多实现案例

类与接口之间支持多实现关系,即一个类可以同时实现多个接口。

首先定义两个接口,代码如下:

java 复制代码
/** 法律规范:接口*/
public interface Law {
    void rule();
}

/** 这一个运动员的规范:接口*/
public interface SportMan {
    void run();
}

然后定义一个实现类:

java 复制代码
/**
 * Java中接口是可以被多实现的:
 *    一个类可以实现多个接口: Law, SportMan
 *
 * */
public class JumpMan implements Law, SportMan {
    @Override
    public void rule() {
        System.out.println("尊长守法");
    }

    @Override
    public void run() {
        System.out.println("训练跑步!");
    }
}

从上述代码可以看出,类与接口之间的多实现关系使得一个类能够遵循多种不同的规范,这在实际编程中具有重要意义,它允许类在不同的功能维度上进行扩展和实现。

5 接口与接口的多继承

在Java中,接口与接口之间支持多继承关系,即一个接口可以同时继承多个接口。需要明确的是,类与接口是实现关系,而接口与接口是继承关系。接口继承接口的本质是将其他接口的抽象方法与本接口进行合并。

以下是案例演示:

java 复制代码
public interface Abc {
    void go();
    void test();
}

/** 法律规范:接口*/
public interface Law {
    void rule();
    void test();
}

 *
 *  总结:
 *     接口与类之间是多实现的。
 *     接口与接口之间是多继承的。
 * */
public interface SportMan extends Law, Abc {
    void run();
}

6 扩展:接口的细节

在接口的使用过程中,有一些语法细节需要注意。这些细节无需刻意背诵,当在开发工具(如IDEA)中出现报错时,能够知道如何修改即可。理解这些细节的关键在于把握抽象的本质。

  1. 当两个接口中存在相同抽象方法的时候

    只需要在实现类中重写一次该方法。此时这个重写的方法,既满足了第一个接口的抽象方法重写要求,也满足了第二个接口的要求。

  2. 实现类能否在继承A类的同时实现其他接口

    可以。继承的父类可类比为"亲爸爸",实现的接口可类比为"干爹"。实现类能够在继承一个类的同时,实现多个接口,但需要将接口中的所有抽象方法全部实现。

  3. 实现类能否在继承一个抽象类的同时实现其他接口

    同样可以。实现类在继承一个抽象类的同时,实现其他多个接口时,需将抽象类和接口中的所有抽象方法全部重写。

  4. 实现类Zi实现了一个接口,还继承了一个Fu类,且接口与父类中有相同方法时

    • 处理办法一:若父类中的方法体能够满足当前业务需求,子类中可不重写该方法。
    • 处理办法二:若父类中的方法体无法满足当前业务需求,则需要在子类中重写该方法。
  5. 如果一个接口中有10个抽象方法,但在实现类中只需要使用其中一个

    可以在接口与实现类之间新建一个中间类(也称为适配器类)。让这个适配器类实现接口,并对接口中的所有方法进行空重写。然后让子类继承这个适配器类,根据实际需求重写需要使用的方法。由于中间类通常不具备实际业务意义,一般将其定义为抽象类,以防止外界创建对象。这种方式在实际开发中能够有效减少实现类的代码冗余,提高代码的灵活性和可维护性。

相关推荐
这周也會开心5 分钟前
云服务器安装JDK、Tomcat、MySQL
java·服务器·tomcat
hrrrrb1 小时前
【Spring Security】Spring Security 概念
java·数据库·spring
小信丶1 小时前
Spring 中解决 “Could not autowire. There is more than one bean of type“ 错误
java·spring
sdgsdgdsgc1 小时前
Next.js企业级应用开发:SSR、ISR与性能监控方案
开发语言·前端·javascript
周杰伦_Jay2 小时前
【Java虚拟机(JVM)全面解析】从原理到面试实战、JVM故障处理、类加载、内存区域、垃圾回收
java·jvm
rit84324995 小时前
基于MATLAB的模糊图像复原
开发语言·matlab
fie88895 小时前
基于MATLAB的声呐图像特征提取与显示
开发语言·人工智能
程序员小凯5 小时前
Spring Boot测试框架详解
java·spring boot·后端
豐儀麟阁贵6 小时前
基本数据类型
java·算法
_extraordinary_6 小时前
Java SpringMVC(二) --- 响应,综合性练习
java·开发语言