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

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 finalint 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 {// 实现接口中定义的方法@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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 {@Overridepublic void myBaseClassFunc(){System.out.println("This is the base class method implementation");}@Overridepublic 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 {@Overridepublic 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 {@Overridepublic void workingStart(){System.out.println("The phone usb interface work starts");}@Overridepublic void workingStop(){System.out.println("The phone usb interface stops working");}
}class Camera implements USBActionable {@Overridepublic void workingStart(){System.out.println("The camera usb interface work starts");}@Overridepublic 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.mzph.cn/news/584995.shtml

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

相关文章

Spring Boot整合GraphQL

RPC选型入门测试系列文章 GraphQL是一种用于API开发的查询语言和运行时环境。它由Facebook开发并于2015年开源。GraphQL的主要目标是提供一种更高效、灵活和易于使用的方式来获取和操作数据。与传统的RESTful API相比&#xff0c;GraphQL允许客户端精确地指定需要的数据&#…

Unity中Shader裁剪空间推导(在Shader中使用)

文章目录 前言一、在Shader中使用转化矩阵1、在顶点着色器中定义转化矩阵2、用 UNITY_NEAR_CLIP_VALUE 区分平台矩阵3、定义一个枚举用于区分当前是处于什么相机 二、我们在DirectX平台下&#xff0c;看看效果1、正交相机下2、透视相机下3、最终代码 前言 在上一篇文章中&…

高光回眸:阿里云容器服务如何全面助力精彩亚运

作者&#xff1a;刘佳旭 谢乘胜 贤维 引言 2023 年&#xff0c;第 19 届杭州亚运会在杭州成功举办。在亚运之光和科技之光的交相辉映下&#xff0c;这届亚运会成为亚运史上首届“云上亚运”&#xff0c;用云计算创造了历史&#xff0c;赛事核心系统和转播全面上云&#xff0c…

[足式机器人]Part2 Dr. CAN学习笔记-自动控制原理Ch1-6根轨迹Root locus

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-自动控制原理Ch1-6根轨迹Root locus 1. 根的作用2. 手绘技巧3. 分离点/汇合点&根轨迹的几何性质 1. 根的作用 G ( s ) s 3 s 2 2 s 4 G\left( s \right) \frac{s3}{s^22s4} G(s)s22s4s3​…

Qt Quick 用cmake怎么玩子项目

以下内容为本人的著作&#xff0c;如需要转载&#xff0c;请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/o-_aGqreuQda-ZmKktvxwA 以往在公司开发众多的项目中&#xff0c;都会出现要求本项目里部分功能模块代码需要具备保密性。如果需要对外输出demo工程&…

如何拍摄好VR全景图片,VR全景图片后期处理有什么技巧

引言&#xff1a; VR全景图片是一种以全景视角呈现场景的图片&#xff0c;通过VR技术可以将用户带入虚拟的环境中&#xff0c;给人一种身临其境的感觉&#xff0c;那么如何才能更好的制作让人满意的全景图片呢&#xff1f; 一&#xff0e;如何拍摄好VR全景图片 1.选择合适的拍…

vue中常见的指令

简单介绍一下常见的vue中用到的指令 v-on 指定当前的事件&#xff0c;语法糖为&#xff0c;如例子所示&#xff0c;指定按钮的事件为addCounter&#xff0c;点击会使变量counter 1 <!DOCTYPE html> <html><head><meta charset"utf-8" />…

Unity JSON编码解码之LitJson 深度剖析

把LitJson的代码库放入到项目中&#xff0c;如图所示:JSON在游戏开发中是一种序列化/反序列化常用的技术&#xff0c;把游戏相关的数据,如地图组成,通过JSON编码&#xff0c;序列化成JSON文本&#xff0c;传输或存储, 要使用的时候再通过JSON技术把文本解析成数据对象&#xff…

2023-12-29 服务器开发-centos-安装php8

摘要: 2023-12-29 服务器开发-centos-安装php8 centos-安装php8 必备条件 Minimal CentOS 8 / RHEL 8User with sudo rightsInternet Connection (1) 更新系统 更新系统 $ sudo dnf update $ sudo dnf upgrade 重启系统 $ sudo reboot (2) 启用 EPEL & Remi 软件库…

【教学类-43-03】20231229 N宫格数独3.0(n=1、2、3、4、6、8、9) (ChatGPT AI对话大师生成 回溯算法)

作品展示&#xff1a; 背景需求&#xff1a; 大4班20号说&#xff1a;我不会做这种&#xff08;九宫格&#xff09;&#xff0c;我做的是小格子的&#xff0c; 他把手工纸翻过来&#xff0c;在反面自己画了矩阵格子。向我展示&#xff1a;“我会做这种&#xff01;” 原来他会…

Android笔记(二十三):Paging3分页加载库结合Compose的实现分层数据源访问

在Android笔记&#xff08;二十二&#xff09;&#xff1a;Paging3分页加载库结合Compose的实现网络单一数据源访问一文中&#xff0c;实现了单一数据源的访问。在实际运行中&#xff0c;往往希望不是单纯地访问网络数据&#xff0c;更希望将访问的网络数据保存到移动终端的SQL…

GitHub Copilot 终极详细介绍

编写代码通常是一项乏味且耗时的任务。现代开发人员一直在寻找新的方法来提高编程的生产力、准确性和效率。 像 GitHub Copilot 这样的自动代码生成工具可以使这成为可能。 GitHub Copilot 到底是什么&#xff1f; GitHub Copilot 于 2021 年 10 月推出&#xff0c;是 GitHub 的…

【无标题】《巴黎图书馆》,又发现一本书

我喜愛看的书(https://img-blog.csdnimg.cn/8cd84d33e6724f09a46831f75abe6464.jpg)在这里插入图片描述

c语言-string.h库函数初识

目录 前言一、库函数strlen()1.1 strlen()介绍1.2 模拟实现strlen() 二、库函数strcpy()2.1 strcpy()介绍2.2 模拟实现strcpy() 三、库函数strcmp()3.1 strcmp()介绍3.3 模拟实现strcmp() 总结 前言 本篇文章介绍c语言<string.h>头文件中的库函数&#xff0c;包含strlen…

网络交换机端口管理会面临的问题

交换机端口管理是跟踪网络交换机及其端口连接详细信息的过程&#xff0c;在大型网络中&#xff0c;交换机端口管理过程通常使用自动化交换机端口管理工具执行。 通过网络交换机端口提供的完全控制和可见性使交换机端口管理工具在管理网络时必不可少&#xff0c;在网络中部署交…

权重函数设计

1e4/(0.5*s^21*s1) 1.4125 抑制驱动器饱和 1e-4*(s1)/(0.001*s1) 10*(s10)/(s1000) 1e-6*(s1)/(0.001*s1) [0.01,0.1],[0.001,1] 0.5*(0.05*s1)/(0.0001*s0.01)

Vue2 - v-model 简介

目录 1&#xff0c;原理1.1&#xff0c;作用于表单元素1.2&#xff0c;作用于自定义组件 2&#xff0c;编译结果展示2.2&#xff0c;表单元素2.1&#xff0c;自定义组件 1&#xff0c;原理 官网参考 v-model 是一个语法糖&#xff0c;最终会生成一个属性和一个事件。并且即可…

彻底理解前端安全面试题(1)—— XSS 攻击,3种XSS攻击详解,建议收藏(含源码)

前言 前端关于网络安全看似高深莫测&#xff0c;其实来来回回就那么点东西&#xff0c;我总结一下就是 3 1 4&#xff0c;3个用字母描述的【分别是 XSS、CSRF、CORS】 一个中间人攻击。当然 CORS 同源策略是为了防止攻击的安全策略&#xff0c;其他的都是网络攻击。除了这…

FFmpeg学习笔记--Centos8安装FFmpeg

1--安装指令 sudo yum install epel-releasesudo yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpmsudo yum install ffmpeg ffmpeg-develffmpeg -version 2--版本信息

【c语言】飞机大战(1)

提前准备好游戏要的素材&#xff0c;可以到爱给网去找&#xff0c;飞机大战我们需要的是一个我方战机图片&#xff0c;一个背景图&#xff0c;三个敌方战机的图&#xff0c;我方战机的图片&#xff0c;敌方战机的图片&#xff0c;并且将图片和.cpp放在同一文件夹下. 这里创建.…