课时86:接口基本定义

简介: 本次课程主要围绕Java中接口展开讲解。首先阐述接口的基本概念,即用于对外部隐藏全部实现细节,是一种比抽象类更严格的抽象类型,包含抽象方法与全局常量,后因Lambda表达式引入,其定义有所扩展 。接着介绍接口的使用原则,如需要被子类实现、子类需复写接口中的抽象方法等,并通过代码示例展示具体实现过程。然后探讨接口实现多继承的特性以及由此带来的对象转型问题,同时讲解接口中方法的访问权限。之后分析抽象类与接口的关系以及接口多继承的情况。最后说明接口在实际开发中的三种应用形式,帮助读者全面深入地理解接口在Java开发中的重要性和使用方法。

课时86:接口基本定义

 

摘要:本次课程主要围绕Java中接口展开讲解。首先阐述接口的基本概念,即用于对外部隐藏全部实现细节,是一种比抽象类更严格的抽象类型,包含抽象方法与全局常量,后因Lambda表达式引入,其定义有所扩展 。

接着介绍接口的使用原则,如需要被子类实现、子类需复写接口中的抽象方法等,并通过代码示例展示具体实现过程。然后探讨接口实现多继承的特性以及由此带来的对象转型问题,同时讲解接口中方法的访问权限。之后分析抽象类与接口的关系以及接口多继承的情况。

最后说明接口在实际开发中的三种应用形式,帮助读者全面深入地理解接口在Java开发中的重要性和使用方法。

1. 接口的基本概念与定义  

2. 接口的使用原则与实现示例  

3. 接口实现多继承及对象转型问题  

4. 抽象类与接口的关系及接口多继承    

 

同学们,今天咱们来一起深入了解一下在Java实际开发中极为重要的概念——接口。在正式开始前,我得跟大家强调一点,当你能够熟练运用抽象类和接口进行程序设计的时候,那就说明你对面向对象的概念已经有了较为深刻的理解。


不过,达到这个程度需要通过大量的代码编写和实践才能实现,可别想着今天高兴一拍脑袋就能完全掌握了,这是不太现实的。

 

01、 接口的基本概念与定义

 

咱们先来看看接口的基本定义。抽象类相比于普通类,最大的优势在于可以控制子类对方法的复写。这确实是我们使用抽象类的主要原因之一,但是在抽象类里,可能还是会存在一些普通方法,而这些普通方法可能涉及到安全或者隐私相关的操作。


在开发过程中,如果想要把所有的实现细节都对外部隐藏起来,这时就可以借助接口来实现,这就是接口的主要概念。可能有些同学对这句话还不太理解,没关系,等我们学到分布式开发的时候,大家就能有更深刻的体会了。一般来说,涉及分布式开发的项目规模都不小,代码量非常庞大,不过这都是后话了。


简单来说,接口可以看作是一种“纯粹”的抽象。最初,接口里只包含抽象方法和全局常量,从这个角度看,它是一种比抽象类还要严格的抽象类型。


但是从 Jdk 1.8开始,随着Lambda表达式概念的引入,接口的定义也得到了扩展,除了抽象方法和全局常量,还可以定义普通方法和静态方法。虽然接口的定义有所放宽,但从设计的角度来讲,接口的组成还是应该以抽象方法和全局常量为主,这才是比较规范的。


在Java里,定义接口主要使用`interface`关键字。下面咱们来定义一个简单的接口。假设我们定义一个名为`message`的接口,这里有个问题大家要注意,抽象类和类本质上都是一种概念,但接口相对特殊一些。


如果接口和类的命名方式结构一样,仅从命名上很难区分哪个是类,哪个是接口。为了便于区分,通常会在接口名称前加上字母“I”,这个“I”其实就是“interface”的缩写。


Interface message{//定义一个接口
   Public static final string INFO=www.Mldn.cn;全局常量
   Public abstract string getInfo();//抽象方法

image.png

这样,我们就完成了一个接口的定义。看起来不难,但是接口有个很明显的问题,它没办法直接创建实例化对象。为什么呢?因为一旦创建了实例化对象,就意味着可以通过这个对象调用方法了,可接口里的抽象方法并没有具体的实现,所以不能创建实例化对象。

 

02、 接口的使用原则与实现示例


关于接口的使用,有这么几个原则:

第一,接口需要被子类实现,在Java里,实现接口用`implements`一个子类可以实现多个父接口;

第二,如果子类不是抽象类,那么必须复写接口里的所有抽象方法;

第三,接口对象可以通过子类对象的向上转型来进行实例化。


代码示例定义一个类`messageTmp1`来实现` message`接口。

Class messagetemp1 implements Imessage{//实现了接口

image.png

但是写完之后,如果这个子类没有复写接口里的抽象方法,编译的时候就会报错,提示不是抽象类,并且没有复写`getInfo`这个抽象方法。所以,我们需要在子类里复写这个方法,比如`return "发送得到一个消息,秘密的消息,有人胖了(不是我)"` 。


接下来,在代码里我们可以这样操作:` Imessage msg = new MessageTmpl();` ,然后可以通过` out.println(msg.getInfo());`来调用方法,还能直接通过接口名调用全局常量,像 Imessage.INFO。写完代码后编译并运行,看看能不能得到预期的结果。

image.png

Return“得到一个消息,秘密的消息,有人胖了(不是我)”
out.println(msg.getInfo());
out.println(Imessage.INFO);

image.png

 

03、 接口实现多继承及对象转型问题


在Java中,使用接口还有一个很重要的原因,就是子类可以通过实现多个接口来实现多继承的概念。我们来定义一个新的接口`IChannel` ,假设它是一个消息通道相关的接口,里面定义一个抽象方法`boolean connect()` ,方法实现里可以简单输出“消息发送通道已经成功建立”,并返回`true` 。


在使用这个接口的时候,可以这样写代码:`if (this.connect()) { // 执行一些操作 } else { // 处理连接失败的情况 }` 。

 

Interface IChannel{
Public abstract boolean connect(){};
Class messageImp1 Implements IMessage,IChannel {
Public string getInfo(){
`if (this.connect()) {
Return“得到一个消息,秘密的消息,有人胖了(不是我)”
Return“通道创建失败无法获取消息”
Public Boolean connect(){
System.out.println (“消息发送通道已经成功建立”)
Return true;

image.png

image.png

但是这个时候就需要考虑一个实际的情况了,关于对象的转型问题了。


咱们把这个接口和之前的` Imessage`接口结合起来看,假设` Messageimp2`这个子类同时实现` Imessage`和`Ichannel`两个接口,这样就实现了多继承。但是这里面存在一个对象转型的问题,大家要注意。


比如` Messageimp2`这个子类创建的对象,它既是` Messageimp2`类型的对象,同时也是` Ichannel`和` Imessage`接口的实例化对象,并且还是`Object`类的子类对象。这就涉及到向上转型的问题了,因为`Object`类可以接收所有的引用类型数据。


image.png

举个例子,代码可以这么写:` message msg = new  messageImp1();` ,` Ichannel chl =(IChannel)msg;` ,虽然` Message`和` Ichannel`这两个接口相互独立,没有直接关系,但因为Messageimpl()子类实现了这两个接口,所以这两个接口的实例之间是可以转换的,不过这种转换仅限于通过这个子类去获取实例的时候。


在Java程序里面接口是不允许去继承父类的,所以接口绝对不会是Object的子类,但是根据之前的分析可以发现,Messageimpl是Object的子类,所以接口一定可以Object接收。另外,`Object`类对象可以接收接口对象,比如`Object Obj =Msg;//向上转型`,更神奇的是,还可以进行` Ichannel Chan =(Ichannel)Obj;`这样的转换,这是因为它们实际上都指向同一个子类对象。

image.png

Imessage msg = new  messageImpl()
Object obj =msg;//向上转型`
Ichannel = (IChannel)msg;`
Ichannel chan = ( Ichannel)obj;
System.out.println(chan.connect())

image.png

Object类对象可以接收所有数据类型,包括基本数据类型、类对象、接口对象、数组。

再来说说接口中方法的访问权限。由于接口描述的是一个公共的定义标准,所以接口里所有抽象方法的访问权限默认都是`public` ,写不写`public`关键字效果是一样的。


比如说,定义两个接口,一个是完整定义,每个方法都明确写了`public`访问权限;另一个是简化定义,没有写访问权限,这两个接口本质上是完全一样的。不过在覆写接口方法的时候,必须使用`public`权限。在实际编写代码的时候,如果为了省事,可以不写访问权限,但如果从代码规范性的角度考虑,还是建议把访问权限写全。


04、 抽象类与接口的关系


还有一点要注意,在实际开发中,实现接口的有可能是抽象类。一个抽象类可以实现多个接口,而一个普通类只能继承一个抽象类,同时可以实现多个接口,但要注意继承和实现的顺序,需要先继承再实现。


比如说,定义一个抽象类`AbstractImp` ,继承某个抽象类(假设为`AbstractBase` )并实现` message`接口,像这样:` Abstract class databaseabstract {。在这个抽象类里,如果定义一个方法getDatabaseConnection()` 。


要注意,只有接口中的抽象方法可以省略`abstract`关键字,抽象类里是不允许省略的。在子类中就需要复写接口中的所有抽象方法,并且可以根据实际情况进行逻辑判断和处理。

 

Abstract class databaseabstract {
Public abstract Boolean getDatabaseConnection();
Public Boolean getDatabaseConnection();

image.png

image.png

image.png

虽然接口无法继承一个父类,但是一个接口却可以通过extends继承若干个父接口:此时就叫接口的多继承,比如定义一个接口`MessageService` ,让它继承` message`和` Ichannel`两个接口,代码可以写成` Interface Iservice extends IMessage,IChannel{


这种接口多继承的情况在类继承里是不允许的,类继承只能继承一个父类。在实现`MessageService`接口的时候,需要复写它所继承的所有接口里的抽象方法。


Interface IChannel {
Public Boolean connect();
Interface Iservice extends IMessage,IChannel{

image.png

image.png

最后,跟大家说一下接口在实际开发中的应用形式,一般有三种:

第一种是用于进行标准设置;

第二种是表示一种操作的能力;

第三种是在远程方法调用,也就是RPC分布式开发中使用,不过这部分内容我们之后再详细讲解。

总之,接口的概念在Java开发里非常重要,大家一定要理解透彻。

相关文章
|
缓存 Ubuntu Linux
Vim编辑器入门指南:安装、基本操作和高级技巧详解 | 适用于Linux系统
Vim编辑器入门指南:安装、基本操作和高级技巧详解 | 适用于Linux系统
2389 0
|
前端开发 Java 数据安全/隐私保护
深入理解 Spring MVC Controller —— 请求参数获取
前言 接上篇《深入理解 Spring MVC Controller —— 请求映射》,上篇主要介绍了处理器方法及请求映射的定义。有了处理器方法 Spring MVC 就可以对请求进行处理,有了请求映射 Spring MVC 就能知道哪些请求应该由哪些处理器方法来处理。
1074 0
深入理解 Spring MVC Controller —— 请求参数获取
|
前端开发 JavaScript Go
VSCode 配置本地服务器
VSCode 配置本地服务器
947 0
VSCode 配置本地服务器
|
8月前
|
机器学习/深度学习 数据库 索引
Transformer 学习笔记 | Encoder
本文记录了学习Transformer模型过程中对Encoder部分的理解,包括多头自注意力机制(Multi-Head Self-Attention)和前馈网络(Feed-Forward Network)的工作原理。每个Encoder Layer包含残差连接(Residual Connection)和层归一化(Layer Normalization),以缓解梯度消失问题并稳定训练过程。文中详细解释了Q、K、V的含义及缩放点积注意力机制(Scaled Dot-Product Attention),并通过图解展示了各组件的工作流程。欢迎指正。
|
1月前
|
安全 Cloud Native Java
Java 模块化系统(JPMS)技术详解与实践指南
本文档全面介绍 Java 平台模块系统(JPMS)的核心概念、架构设计和实践应用。作为 Java 9 引入的最重要特性之一,JPMS 为 Java 应用程序提供了强大的模块化支持,解决了长期存在的 JAR 地狱问题,并改善了应用的安全性和可维护性。本文将深入探讨模块声明、模块路径、访问控制、服务绑定等核心机制,帮助开发者构建更加健壮和可维护的 Java 应用。
154 0
TortoiseSVN安装使用教程(超详细)
TortoiseSVN安装使用教程(超详细)
10336 58
|
7月前
|
测试技术
课时108:用例图
课时108介绍了用例图的设计与描述。用例图用于展示系统中不同角色的功能分配,如系统管理员拥有系统初始化、备份、公告发布等功能,而普通管理员仅负责公告管理。通过建立Use Cases图,可以直观呈现各角色的具体功能,帮助在项目设计阶段明确角色权限和职责。用例图是详细设计和概要设计的重要组成部分,有助于清晰表达系统的功能结构。
170 1
Nest.js 实战 (十三):实现 SSE 服务端主动向客户端推送消息
这篇文章介绍了在Nest.js应用中使用Server-Sent Events (SSE)的技术。文章首先讨论了在特定业务场景下,为何选择SSE而不是WebSocket作为实时通信系统的实现方式。接着解释了SSE的概念,并展示了如何在Nest.js中实现SSE。文章包含客户端实现的代码示例,并以一个效果演示结束,总结SSE在Nest.js中的应用。
427 0
Nest.js 实战 (十三):实现 SSE 服务端主动向客户端推送消息
|
人工智能 NoSQL 程序员
程序员常用的工具软件推荐(提高工作效率和代码质量)
程序员常用的工具软件推荐(提高工作效率和代码质量)
228 0