avatar

一条在知识海洋的咸鱼

这个家伙很懒,啥也没有留下😋

  • 首页
  • Linux
  • OCJP
  • Java核心技术卷
  • J2EE相关标准
  • 深入理解Java虚拟机
  • NIO与SOcket编程技术指南
  • Java多线程编程核心技术
  • Redis开发与运维
  • Spring Cloud Alibaba 微服务原理与实践
  • DevOps
  • Docker
  • MySQL必知必会
  • AI自学路线
  • Spring Boot 编程思想(核心篇)
主页 第四章 接口
文章

第四章 接口

发表于 2021-05-7 更新于 2026-06- 10
作者 Administrator
15~20 分钟 阅读

开发声明、实现和/或继承接口的代码,并使用 @Override注解

  • 接口
    • 为什么接口可以多实现,类只能单继承
    • @override注解
  • JDK8接口新功能
  • 默认Default方法
    • 定义默认方法
  • 重写默认default方法
  • 具有默认deafult方法的多个接口继承
  • 接口的静态方法

接口

  • 与类一样,接口具有public或default的可访问性
  • 接口中声明的字段默认为 PUBLIC、 STATIC 和 FINAL。与方法一样,即使您没有指定它们,编译器也会这样对待它们。即默认字段都为静态常量
    image.png
    所以接口中的成员变量不能未private,且必须要初始化赋值
  • 接口可以extends任意数量的接口

为什么接口可以多实现,类只能单继承

如果你可以从多个类继承,当方法签名相同时,无法选择具体是哪个父类的方法,但接口因为只是定义,实现类是要重写父类方法的,避免了该问题

  • 方法只有返回类型不同时,由于返回类型在方法的签名中没有被考虑,Java 编译器会生成一个错误:
interface Truck {
    void accelerate();
}
interface CompactCar {
    int accelerate();
}
class Car implements Truck, CompactCar {
    // Java will complain about duplicate methods
    // and incompatible return types
    public void accelerate() {
        // implementation
    }
    public int accelerate() {
        // implementation
    }
}

image.png
顺带提一句重载是可以改变方法的返回类型的

@override注解

为什么要加这个注解,因为的方法没有正确重写或实现该方法,编译器将生成错误。这是这个注解的的唯一功能。这在一些情况下很有用,比如一个输入错误导致了一个不太明显的错误:

interface CompactCar {
    int accelerate();
}
class Car implements CompactCar {
    // Compiler will mark an error about method
    // "acelerate" not overriding or implementing something
    @Override
    public int acelerate() {
        // implementation
    }
}

JDK8接口新功能

java8提供了默认的方法,我们不必为它们提供实现,因为它们是非抽象的方法。允许使用带有方法体的方法

  • 原因
    如果一个接口被数百个类实现,现在要修改该接口,增加一个方法
    1.数百个实现类必须都要增加实现否则编译报错,量大
    2.某些原因无法更新或访问实现类代码
    3.在功能上新增加的方法对于某些实现类来说并不需要,即不需要手动重写

默认Default方法

将默认方法添加到接口的主要原因是为了支持接口演进,为接口添加新功能,同时确保与为旧版本编写的代码兼容。

  • 与抽象类的区别
    1.抽象类单继承,接口可多实现
    2.抽象类有实例字段具有状态属性,接口不可以

定义默认方法

interface Processable {
    void processInSequence();
    default void processInParallel() {
        /** Default implementation goes here */
    }
}
  • 默认方法是public的,就像接口的其他方法一样
  • 默认方法不能是final的。接口中所有方法都不能为final
  • 默认方法无法被synchronized加锁,应该在实现类中实现
    image.png
    image.png
  • 不能为Object类方法提供默认方法
    如果接口具有带有这些签名的方法,编译器将抛出错误。原因是这些方法都是关于对象的状态。因为接口没有状态,所以这些方法应该在实现类中
boolean equals(Object o)
int hashCode()
String toString()

image.png

重写默认default方法

方法定义使用上,类的优先级高于接口,如果一个类重写了default的方法,那么类方法就是使用的方法。就和其他只是定义了方法签名的没有方法体的方法一样

  • 即使该类将默认方法重新定义为 abstract,这也是正确的
interface Processable {
    void processInSequence();
    default void processInParallel() {
        System.out.println("Default parallel");
    }
}
// Class Task has to be abstract
abstract class Task implements Processable {
    @Override
    public void processInSequence() {
        System.out.println("Processing in sequence");
    }
    @Override
    public abstract void processInParallel();
}
  • 调用方法的默认实现,可以使用接口的名称,后面跟着关键字 super
public void processInParallel() {
    Processable.super.processInParallel();
}
  • 当一个类的继承实例方法覆盖了默认的接口方法,则使用的也是继承的实例类重写的方法
interface Processable {
    default void processInParallel() {
        System.out.println("Default parallel");
    }
}
class Process {
    public void processInParallel() {
        System.out.println("Class parallel");
    }
}
public class Task
        extends Process implements Processable {
    public static void main(String args[]) {
        Task t = new Task();
        t.processInParallel(); //Class parallel
    }
}

具有默认deafult方法的多个接口继承

两个接口具有相同的默认方法被子类实现时,如果子类不覆盖该默认方法则会编译报错

编译器不知道选择哪个,所以它会生成一个错误。在这种情况下,Task 必须提供一个实现(遵循前面的规则,即更具体的接口(或类)总是会胜过不那么具体的接口)来覆盖接口缺省方法并解决问题:

interface Parallelizable1 {
    default void processInParallel() {
        System.out.println("Parallelizable parallel");
    }
}
public class Task
        implements Processable1, Parallelizable1 {
    @Override
    public void processInSequence() {
        System.out.println("Processing in sequence");
    }
    public static void main(String args[]) {
        Task t = new Task();
        t.processInParallel();
    }
}

报错,必须要重写该默认方法
image.png

接口的静态方法

1.默认为public
2.不能被继承,但是类的静态方法可以被继承
3.使用时必须在方法前面加上接口名,因为接口不能被实例化

OCJP
许可协议: 
分享

相关文章

9月 6, 2021

关于这篇OCP-Java专题说明

5月 28, 2021

三十章 本地化

通过使用 Locale 对象读取和设置 Locale。创建并读取属性文件。为每个区域设置构建资源包,并在应用程序中加载资源包。本地化设置语言环境本地化设计一个能够处理不同语言和地区的应用程序。最常见的是消息、日期和数字。java.util.LocaleLocale类基本上代表一种语言和一个国家获得机

5月 27, 2021

第二十九章 JDBC API

了解JDBC API 核心的接口,包括 Driver、 Connection、 Statement 和 ResultSet 接口及其与提供者实现的关系。使用 DriverManager 类(包括 JDBC URL)标识连接到数据库所需的组件。从数据库提交查询和读取结果,包括创建语句、返回结果集、遍历

下一篇

第五章 枚举

上一篇

第三章 内部类

最近更新

  • 55 异常兜底:工具失败、非法输出、空检索与超时
  • 54 Agent Memory:短期记忆、用户上下文与摘要
  • 53 Human-in-the-loop:让关键动作暂停、确认与恢复
  • 52 工单 Tool:字段校验、创建结果与失败补偿
  • 51 订单 Tool:Mock、鉴权、状态解析与脱敏

热门标签

java基础 微服务 maven Spring Tomcat DDD Linux Linux基础 SQL基础 数据结构算法

目录

©2026 一条在知识海洋的咸鱼. 保留部分权利。

使用 Halo 主题 Chirpy