【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个抽象方法,但在实现类中只需要使用其中一个

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

相关推荐
带刺的坐椅1 分钟前
能用 Java8 开发 MCP(或 MCP Server),这才是 MCP 自由(Solon AI MCP)!
java·spring·ai·solon·mcp·mcp-server
周Echo周7 分钟前
8、constexpr if、inline、类模版参数推导、lambda的this捕获---c++17
linux·开发语言·c++·算法·vim
Eugene__Chen7 分钟前
内存管理详解(曼波脑图超详细版!)
java·jvm·windows
逐光沧海7 分钟前
函数对象-C++
开发语言·c++·算法
虾球xz12 分钟前
游戏引擎学习第238天:让 OpenGL 使用我们的屏幕坐标
学习·游戏引擎
Java知识库27 分钟前
Java基础知识面试题(已整理Java面试宝典pdf版)
java·面试·程序员·编程·面试题
SimonKing1 小时前
【Spring Boot配置终极指南】1分钟让你精准指定配置文件,使应用部署游刃有余!
java·后端
axinawang1 小时前
SpringBoot整合Java Web三大件
java·前端·spring boot
炯哈哈1 小时前
【上位机——MFC】MFC入门
开发语言·c++·mfc·上位机
SsummerC1 小时前
【leetcode100】一和零
开发语言·python·leetcode·动态规划