Java核心技术卷接口的实现与继承多态知识梳理总结

news2025/1/23 4:01:34

Java核心技术卷接口的实现与继承多态知识梳理总结

接口的概念

在Java程序设计语言中,接口不是类,而是对希望符合这个接口的类的一组需求。

form: Java核心技术·卷 I(原书第11版) 基础知识 by 凯 S.霍斯特曼

在Java中,接口(Interface)是一种抽象类型,它定义了一组方法的签名(方法名、返回类型、参数列表)但没有提供方法的实现,即接口不能够被实例化。类实现(implements)接口,从而承诺提供接口定义的所有方法的实现。接口提供了一种方式来实现多重继承,因为一个类可以实现多个接口。

为何使用接口编程

接口编程是一种促进良好软件设计实践的方法,可以改善代码的结构、可维护性和可扩展性。通过定义清晰的接口,我们能够更好地组织和管理复杂的软件系统,使用接口主要有以下几种原因:

  1. 抽象和解耦: 接口提供了一种抽象层,使得实现和使用代码可以相互独立。通过定义接口,我们可以将系统的不同组件解耦,降低它们之间的依赖关系。这有助于提高代码的模块性和可维护性。

  2. 多态性: 接口允许多态性,即一个对象可以以多种形式存在。通过使用接口,我们可以编写可以操作不同类型对象的通用代码,从而增加了代码的灵活性和可扩展性。

  3. 规范标准: 接口定义了一组规范和标准,用于描述类或模块的行为。这有助于团队协作,因为开发人员可以遵循相同的接口规范,确保代码的一致性和可预测性。

  4. 测试和调试: 接口使得单元测试更加容易。通过编写适当的接口,可以使用模拟对象或模拟接口来测试代码的不同部分,而无需实际实现所有相关的类或模块。

  5. 提高可替代性: 通过使用接口,我们可以在不影响整个系统的情况下替换具体的实现。这使得在不修改调用方代码的情况下更容易切换实现,从而提高系统的可替代性。

  6. 降低耦合度: 接口编程有助于减少代码之间的紧密耦合。这意味着当一个模块发生变化时,其他模块不太可能受到影响,从而提高了代码的可维护性和稳定性。

  7. 提高代码的可读性和理解性: 接口提供了一种清晰的契约,描述了类或模块的期望行为。这有助于提高代码的可读性,并使其他开发人员更容易理解和使用你的代码。

定义接口

注意:接口的访问控制符只能是包默认(default)和public两种类型

使用 interface 关键字来定义接口。接口可以包含方法签名、常量(静态 final 域),但不能包含字段(成员变量)或实现方法的代码块,并且接口中的所有方法都是自动视为public的,故不需要书写public,并且接口中的常量会被默认置为public static final,并且必须进行初始化操作

public interface MyInterface {
    // 接口方法的签名 不需要实现
    void myMethod();

    // 接口中的常量 隐式声明为 public static final
    int MY_CONSTANT = 42;
}

在上述接口中,我们定义了一个返回值为void,无需形参的方法签名,该方法本质上是abstract的,只是在接口实现中,未实现方法默认abstract,所以不用书写关键字,当然可以加上显式声明,不过并不推荐:

在这里插入图片描述

接口默认方法(Java 8+)

Java8之后的版本,接口可以包含默认方法,这是在接口中提供方法实现的新特性。实现类可以选择重写默认方法。

public interface MyInterface {
    // 抽象方法
    void myMethod();

    // 默认方法
    default void defaultMethod() {
        System.out.println("Default implementation of defaultMethod");
    }
}

静态方法(Java 8+):

Java8之后的版本,接口可以包含静态方法,这是在接口级别提供工具方法的一种方式,即可以通过接口名调用静态方法。

public interface MyInterface {
    // 静态方法
    static void staticMethod() {
        System.out.println("Static method in interface");
    }
}

实现接口

警告:在接口声明中,没有将类中方法声明为public,这是因为在接口中的所有方法都自动是public。不过,在实现接口时,必须把方法声明为public;否则,编译器将认为这个方法的访问属性是包可见性,这是类的默认访问属性,之后编译器就会报错,指出你试图提供更严格的访问权限。

from: Java核心技术·卷 I(原书第11版) 基础知识 by 凯 S.霍斯特曼 page 224(根据博文进行了简单修改)

抽象类实现

抽象类实现接口,可以不扩展方法

interface InterfaceOne{
    void occupyLocationFunc();
}

abstract class AbstractClass implements InterfaceOne{
	// code   
}

单接口实现

在类使用 implements 关键字来实现接口。实现接口的可实例化类必须提供接口中定义的所有方法的具体实现

public class MyClass implements MyInterface {
    // 实现接口中定义的方法
    @Override
    public void myMethod() {
        // 具体的实现逻辑
        System.out.println("Implementation of myMethod and MY_CONSTANT is " + MY_CONSTANT);
    }
}

注意:在外部访问接口中的常量:

InterfaceName.constant_name			// 接口名.常量名

多接口实现

一个类可以实现多个接口,通过使用逗号分隔接口名称。

public class MyMultiInterfaceClass implements Interface1, Interface2 {
    // 实现接口中定义的方法
    // ...
}
多接口实现时的准确指定

在 Java 中,一个类可以实现多个接口,而这些接口可能包含相同签名的默认方法。当一个类实现多个接口,并且这些接口中有相同签名的默认方法时,需要使用 super 关键字明确指定调用哪个接口的默认方法。

考虑以下的例子:

interface InterfaceA {
    default void defaultMethod() {
        System.out.println("Default method in InterfaceA");
    }
}

interface InterfaceB {
    default void defaultMethod() {
        System.out.println("Default method in InterfaceB");
    }
}

class MyClass implements InterfaceA, InterfaceB {
    @Override
    public void defaultMethod() {
        InterfaceA.super.defaultMethod(); // 明确指定调用 InterfaceA 的默认方法
        InterfaceB.super.defaultMethod(); // 明确指定调用 InterfaceB 的默认方法
        System.out.println("Overridden default method in MyClass");
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass myObject = new MyClass();
        myObject.defaultMethod();
    }
}

在这个例子中,MyClass 类实现了两个接口 InterfaceAInterfaceB,并且这两个接口都定义了相同签名的默认方法 defaultMethod。在 MyClass 中,通过使用 InterfaceA.super.defaultMethod()InterfaceB.super.defaultMethod() 明确指定调用哪个接口的默认方法。

这种情况下,使用 super 关键字的语法为:

InterfaceName.super.defaultMethod();

其中,InterfaceName 是接口的名称。这样就能够避免默认方法冲突的问题,同时在实现类中提供自定义的实现。

接口继承

接口可以扩展其他接口,使用 extends 关键字。

public interface ExtendedInterface extends MyInterface {
    // 可以定义新的方法或使用继承的方法
    // ...
}

接口演化

接口演化是指的在接口的第一个版本实现后,又增加了新的方法签名(先允许我这样说,那么会产生一个问题,我们在原有接口基础上增加一个方法签名:

public interface MyInterface {
    int MY_CONSTANT = 42;

    void myMethod();
    void printHelloWorldForUser(String user_name);
}

假如在此之前我已经实现了一个类:

public class MyClass implements MyInterface {
    @Override
    public void myMethod() {
        System.out.println("Implementation of myMethod and MY_CONSTANT is " + MY_CONSTANT);
    }
}

那么增加过后,我的类将无法编译,因为我并未提供完整的接口实现,void printHelloWorldForUser(String user_name)并没有实现(已经编译好的不受影响),所以无法编译,此时就需要我们的默认方法实现:

public interface MyInterface {
    int MY_CONSTANT = 42;

    void myMethod();
    default void printHelloWorldForUser(String user_name){
        System.out.println("Hi " + user_name + " Hello World");
    }
}

使用默认方法以保证源代码兼容

接口与继承同时实现

在类实现接口时,也可以从超类进行继承,不过继承必须写在前面,否则会报错:

abstract class MyBaseClass{
    abstract void myBaseClassFunc();
}

public class MyClass extends MyBaseClass  implements MyInterface {
    @Override
    public void myBaseClassFunc(){
        System.out.println("This is the base class method implementation");
    }

    @Override
    public void myMethod() {
        System.out.println("Implementation of myMethod and MY_CONSTANT is " + MY_CONSTANT);
    }
}
接口与抽象类的差异

由于Java中不能使用像C++中的多重继承,因为Java设计者认为多重继承会使得代码过于复杂,抽象类由于每次只能扩展一个类,其无法满足多扩展的需求

C++注释:C++具有多重继承特性,随之带来了一些复杂的特性,如虚基类、控制规则和横向指针类型转换,等等。很少有C++程序员使用多重继承,甚至有些人说就不应该使用多重继承。也有些程序员建议只对“混合”风格的继承使用多重继承。在“混合”风格中,一个主要基类描述父对象,其他的基类(所谓的混合类)提供辅助特性。这种风格类似于一个Java类扩展一个基类且派生并实现多个接口。

from: Java核心技术·卷 I(原书第11版) 基础知识 by 凯 S.霍斯特曼 page 230

解决默认方法冲突
  • 超类优先:如果超类提供了一个具体方法,同名而且有相同参数类型的默认方法会被忽略。
public interface MyInterface {
    default void printHello(){
        System.out.println("Hello World");
    }
}
class BaseClass{
    public void printHello(){
        System.out.println("Hello Java");
    }
}

public class SubClass extends BaseClass implements MyInterface {
    public static void main(String[] args){
        SubClass object = new SubClass();
        object.printHello();
    }
}

在这里插入图片描述

  • 接口冲突:如果一个接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型(不论是否是默认参数)相同的方法,必须覆盖这个方法来解决冲突。
public interface MyInterfaceOne {
    default void printHello(){
        System.out.println("Hello World");
    }
}

interface MyInterfaceTwo{
    default void printHello(){
        System.out.println("Hello Java");
    }
}
public class SubClass implements MyInterfaceOne, MyInterfaceTwo {
    @Override
    public void printHello() {
        MyInterfaceOne.super.printHello();
        // System.out.println("Hello IDEA");
    }

    public static void main(String[] args){
        SubClass object = new SubClass();
        object.printHello();
    }
}

在这里插入图片描述

接口的回调操作

回调(callback)是一种常见的程序设计模式。在这种模式中,可以指定某个特定事件发生时应该采取的动作。例如,按下鼠标或选择某个菜单项时,你可能希望完成某个特定的动作。

form: Java核心技术·卷 I(原书第11版) 基础知识 by 凯 S.霍斯特曼 page 233

我们通过模拟日常生活中数码产品USB接入电脑的操作来模拟接口回调:

  • 定义接口USBInterface并定义工作状态方法签名
interface USBActionable {
    void workingStart();
    void workingStop();
}
  • 实现接口扩展不同工作状态
class Phone implements USBActionable {
    @Override
    public void workingStart(){
        System.out.println("The phone usb interface work starts");
    }

    @Override
    public void workingStop(){
        System.out.println("The phone usb interface stops working");
    }
}

class Camera implements USBActionable {
    @Override
    public void workingStart(){
        System.out.println("The camera usb interface work starts");
    }

    @Override
    public void workingStop(){
        System.out.println("The camera usb interface stops working");
    }
}
  • Computer中定义进行USB接入时的回调行为(这里为了演示方便,定义为静态方法)
class Computer{
    public static void printWorkingStatus(USBActionable other){
        other.workingStart();
        other.workingStop();
    }
}
  • Main类中运行
public class Main {
    public static void main(String[] args){
        Phone phone = new Phone();
        Camera camera = new Camera();
        Computer.printWorkingStatus(phone);
        Computer.printWorkingStatus(camera);
    }
}

在这里插入图片描述

接口多态实现

基类引用实现运行时多态

在原有代码基础上进行修改:

public class Main {
    public static void main(String[] args){
        USBActionable phone = new Phone();
        USBActionable camera = new Camera();
        phone.workingStart();
        camera.workingStart();
    }
}

我们使用接口类型的变量引用对应的实现了接口的对象,运行时,会根据引用的对象来调用对应的方法

在这里插入图片描述

方法签名重载实现编译时多态

interface InterfaceOne{
    void occupyLocationFunc();
    void occupyLocationFunc(Object occupy_variable);
}

个人觉得这种东西区分一下即可,毕竟实现接口就已经重写覆盖了对应的方法,实质上也就是一种编译时多态

接口继承实现多态传递

interface InterfaceOne{
    default void occupyLocationFunc(){
        System.out.println("occupyLocationFunc of InterfaceOne");
    };
}


interface InterfaceTwo extends InterfaceOne{
    default void printHelloWorld(){
        System.out.println("printHelloWorld of InterfaceTwo");
    }
}


class TestClass implements InterfaceTwo{

}


public class ExtendsClassMain {
    public static void main(String[] args) {
        InterfaceOne one = new TestClass();
        one.occupyLocationFunc();
    }
}

在上述代码中,我们以最外层接口类型InterfaceOne变量来指向引用的TestClass对象,并调用其继承自InterfaceOne的方法,实现了多态的传递

工程拓展-接口与API

身边很多人经常挂在嘴边,但是不明所以,所以一并写下

接口(Interface)和API(Application Programming Interface)是软件开发中经常使用的两个术语,它们有不同的含义和用法。

接口(Interface)

  1. 接口定义: 在面向对象编程中,接口是一种抽象类型,它定义了一组方法(或方法签名)而没有提供方法的具体实现。接口可以包含常量(静态不可变的变量),但通常主要包含方法声明。

  2. 实现接口: 类可以实现一个或多个接口,表示该类将提供接口中定义的所有方法的具体实现。通过实现接口,类可以达到多继承的效果。

  3. Java中的接口: 在Java编程语言中,接口是通过interface关键字定义的,类通过implements关键字来实现接口。接口的实例方法默认是public abstract的。

public interface MyInterface {
    void myMethod();
    int myAnotherMethod();
}

API(Application Programming Interface)

  1. API定义: API是一组定义了软件组件之间交互的规范。它可以包含类、函数、协议、工具等,允许不同的软件系统之间进行交互和集成。

  2. 种类: API的种类很多,包括库级别的API、操作系统级别的API、网络API等。在编程中,常见的是库级别的API,用于与库或框架进行交互。

  3. 示例: Java API指的是Java编程语言提供的类和方法,而不同的库、框架、操作系统也都有各自的API。例如,Java提供的java.util.List接口和ArrayList类就是Java API的一部分。

List<String> myList = new ArrayList<>();
myList.add("Hello");
myList.add("World");

区别

  1. 定义: 接口是一种抽象类型,定义了一组方法的声明而没有具体实现。API是一组规范,可以包括接口、类、函数等,用于软件组件之间的交互。

  2. 用途: 接口用于定义类的合同,规定了类应该提供哪些方法,而API用于描述各种软件组件之间的交互方式。

  3. 实现: 类可以实现一个或多个接口,但接口本身并不提供具体的实现。API可以包含具体的实现,例如库或框架提供的类和方法。

  4. 示例: java.util.List是一个接口,而Java API包含了许多类似ArrayList的具体实现,以及其他各种类和方法。

总体而言,接口是一种抽象的概念,用于定义类的契约,而API是一组规范,用于描述软件组件之间的交互。在软件开发中,开发人员通常需要实现接口来满足一定的规范,并使用各种API来构建应用程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1344132.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

园林机械部件自动化三维测量检测形位公差-CASAIM自动化三维检测工作站

随着园林机械的广泛应用&#xff0c;对其机械部件的精确测量需求也日益增加。传统的测量方法不仅效率低下&#xff0c;而且精度难以保证&#xff0c;因此&#xff0c;自动化三维测量技术成为了解决这一问题的有效途径。本文将重点介绍CASAIM自动化三维检测工作站在园林机械部件…

线性代数笔记1 12.30

学习视频&#xff1a; 1.4 行列式的计算&#xff08;一&#xff09;_哔哩哔哩_bilibili 以下内容&#xff0c;包含&#xff1a; 二阶三阶行列式 n阶行列式 行列式的性质 行列式按行展开

PiflowX组件-WriteToKafka

WriteToKafka组件 组件说明 将数据写入kafka。 计算引擎 flink 有界性 Streaming Append Mode 组件分组 kafka 端口 Inport&#xff1a;默认端口 outport&#xff1a;默认端口 组件属性 名称展示名称默认值允许值是否必填描述例子kafka_hostKAFKA_HOST“”无是逗号…

9种卷积注意力机制创新方法汇总,含2024最新

今天咱们来聊聊卷积注意力机制。 相信各位在写论文的时候都苦恼过怎么更好地改模型&#xff0c;怎么更高效地提高模型的性能和泛化能力吧&#xff1f;我的建议是&#xff0c;不妨考虑考虑卷积注意力。 卷积注意力机制是一种通过关注输入数据中的不同部分来改进模型性能的方法…

数据结构之树 --- 二叉树

目录 定义二叉树的结构体 二叉树的遍历 递归遍历 非递归遍历 链式二叉树的实现 二叉树的功能接口 先序遍历创建二叉树 后序遍历销毁二叉树 先序遍历查找树中值为x的节点 层序遍历 上篇我们对二叉树的顺序存储堆进行了讲述&#xff0c;本文我们来看链式二叉树。 定…

台式电源质量如何检测?纳米软件为您科普

一、外观检测 观察台式机电脑电源外观是否有损伤、烧焦&#xff0c;电源线是否有破损、短线的情况。观察电源的电压、电流、功率等参数&#xff0c;是否符合台式机电脑。 二、直观检测 开通电源&#xff0c;如果所有指示灯不亮&#xff0c;风扇没有声音&#xff0c;电源损坏的可…

yolov5 主要流程

1.介绍 本文包含了有关yolov5目标检测的基本流程&#xff0c;包括模型训练与模型部署&#xff0c;旨在帮助小伙伴们建立系统的认知&#x1f496;&#x1f496; YOLO是 "You only look once "的首字母缩写&#xff0c;是一个开源软件工具&#xff0c;它具有实时检测…

Mysql高阶语句及存储过程

目录 空值(NULL) 和 无值() 的区别&#xff1a; 正则表达式&#xff1a; 存储过程&#xff1a; 创建存储过程&#xff1a; 存储过程的参数&#xff1a; 存储过程的控制语句&#xff1a; mysql高阶语句 case是 SQL 用来做为if&#xff0c;then&#xff0c;else 之类逻辑的…

php-fpm运行一段时间,内存不足

目录 一&#xff1a;原因分析 二&#xff1a;解决 三:观察系统情况 php-fpm运行一段时间&#xff0c;内存不足&#xff0c;是什么原因呢。 一&#xff1a;原因分析 1:首先php-fpm的配置 &#xff08;1&#xff09;启动的进程数 启动的进程数越多,占用内存越高; 2:其次…

Android studio CMakeLists.txt 打印的内容位置

最近在学习 cmake 就是在安卓中 , 麻烦的要死 , 看了很多的教程 , 发现没有 多少说对打印位置在哪里 , 先说一下版本信息 , 可能你们也不一样 gradle 配置 apply plugin: com.android.applicationandroid {compileSdkVersion 29buildToolsVersion "29.0.3"defau…

2023开发原子开放者大会:AI时代的前端开发,挑战与机遇并存

前言 12月16日&#xff0c;以“一切为了开发者”为主题的开放原子开发者大会在江苏省无锡市开幕。江苏省工业和信息化厅厅长朱爱勋、中国开源软件推进联盟主席陆首群等领导和专家参加开幕式&#xff0c;工业和信息化部信息技术发展司副司长王威伟、江苏省工业和信息化厅副厅长…

视频流媒体直播云服务管理平台EasyNVS长时间运行出现崩溃情况是什么原因?该如何解决?

EasyNVS云管理平台具备汇聚与管理EasyGBS、EasyNVR等平台的能力&#xff0c;可以将接入的视频资源实现统一的视频能力输出&#xff0c;支持远程可视化运维等管理功能&#xff0c;还能解决设备现场没有固定公网IP却需要在公网直播的需求。 有用户反馈&#xff0c;在长时间不间断…

虚拟机和电脑如何传送文件

一.桥接 &#xff08;实现电脑和虚拟机在同一网段&#xff09; 虚拟机上网盘设置 二.属性---文件共享设置 1打开属性&#xff0c;点击共享 2.添加共享人为全部人&#xff0c;并修改权限为读写模式 3.点击高级共享&#xff0c;选定此文件夹 4.点击网络和共享中心&#xff0c;划…

js实现前端下载图片和文件资料

说明&#xff1a;下载图片和文档资料是两种不同的方式&#xff0c;所以需要先判断下载的是图片还是word&#xff0c;excel等文件资料 目录 1.文件资料下载&#xff1a; 2.图片资源下载 1.文件资料下载&#xff1a; window.location.href 文件路径; handleClick(item) {let…

S32K312程序快速集成软件看门狗的方法

S32K312的软件看门狗配置比较复杂&#xff0c;如果靠纯手工在外设中进行配置&#xff0c;非常费时间&#xff0c;还不一定好用。 想要快速使用S32K312的软件看门狗&#xff0c;我探索一翻后做了总结&#xff1a; 1、先创建一个官方的示例代码工程&#xff08;Wdg_Example_S32K…

世界经济论坛制定了五项指导原则,实现跨OT环境的网络安全。

内容概述&#xff1a; 世界经济论坛在其题为“解锁工业环境中的网络弹性&#xff1a;五项原则”的报告中列出&#xff1a;原则一&#xff1a;执行全面风险管理OT 环境、原则二&#xff1a;确保OT工程师和安装操作员对OT网络安全负责、原则三&#xff1a;与高层组织领导、战略规…

一文了解无线通信 - NB-IOT、LoRa

NB-IOT、LoRa 目录概述需求&#xff1a; 设计思路实现思路分析 NB-IOT1.LoRa2.区别 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wait for change,chall…

main 函数参数!它们有什么作用?

文章目录 1 主函数定义的标准方式2 为什么main函数需要参数&#xff1f;3 不写参数是否可以&#xff1f;4 两个参数有什么用&#xff1f;5 怎么用&#xff1f;6 总结 1 主函数定义的标准方式 int main (void) { body } //第一种 int main (int argc, char *argv[]) { body …

矩阵微分笔记(2)

目录 前言基本求导规则1. 向量变元的实值标量函数1.1 4个法则1.2 常用公式 2. 矩阵变元的实值标量函数2.1 4个法则2.2 常用公式 参考 前言 这篇笔记的内容是基于参考的文章写出的&#xff0c;公式部分可以会沿用文章本来的式&#xff0c;但会加入我自己的一些思考以及注释&…

Spring-6-事务管理

事务是构建可靠企业级应用程序的最关键部分之一。 最常见的事务类型是数据库操作。 在典型的数据库更新操作中&#xff0c;首先数据库事务开始&#xff0c;然后数据被更新&#xff0c;最后提交或回滚事务(根据数据库操作的结果而定)。但是&#xff0c;在很多情况下&#xff0…