JavaSE:抽象类和接口
目录
一、前言
二、抽象类
(一)抽象类概念
(二)使用抽象类的注意事项
(三)抽象类的作用
三、接口
(一)接口概念
(二)接口语法规则
(三)接口的使用
(四)接口特性
(五)实现多个接口
(六)接口间的继承
(七)使用接口给对象数组排序
(八)Clonable 接口和深拷贝
四、抽象类与接口的区别
五、总结
一、前言
大家好啊,蜡笔小欣前面和大家分享了Java中的类与对象、继承和多态等内容,相信大家也能感受到 Java的魅力所在,今天小欣将给大家分享Java中的抽象类和接口。在Java中,抽象类和接口是两个重要的概念,用于创建可重用和可扩展的代码。它们允许我们在不同类之间建立契约,同时保持实现代码的灵活性。
二、抽象类
(一)抽象类概念

说明:
1.矩形、三角形、圆形都是图形,因此和Shape类的惯性应该是继承关系,
2.虽然图形图Shape中也存在draw方法,但由于Shape类并不是具体的图形,因此其内部的draw方法实际是没有办法实现的,
3.由于Shape类没有办法描述一个具体的图形,导致其draw()方法无法具体实现,因此可以将Shape类设计为“抽象类”。
class Shape {public void draw() {System.out.println("Shape::draw()");}
}class Rect extends Shape {public void draw() {System.out.println("菱形");}
}class Triangle extends Shape {@Overridepublic void draw() {System.out.println("三角形");}
}class Cycle extends Shape {@Overridepublic void draw() {System.out.println("圆形");}
}public class Test {public static void main(String[] args) {Rect rect = new Rect();Triangle triangle = new Triangle();Cycle cycle = new Cycle();Shape[] shapes = {triangle, rect, cycle};for (Shape s : shapes) {s.draw();}}
}
在打印图形例子中,父类 Shape 中的 draw 方法好像并没有什么实际工作, 主要的绘制图形都是由 Shape 的各种子类的 draw 方法来完成的. 像这种没有实际工作的方法, 我们可以把它设计成一个 抽象方法, 包含抽象方法的类我们称为抽象类。
abstract class Shape{public abstract void draw();
}
在 draw 方法前面加上 abstract 关键字就变成了抽象方法,但是包含抽象方法的类,必须用 abstract 修饰。
(二)使用抽象类的注意事项
public class Test {public static void main(String[] args) {Shape shape = new Shape();}
} 报错如下图所示:

2.抽象方法是不能用 private 修饰的
abstract class Shape{private abstract void draw();
}
报错如下图所示:

3.抽象方法不能被final和static修饰,因为抽象方法要被子类重写
抽象类中可以包含其他的非抽象方法,也可以包含字段,这里的非抽象方法和普通方法的挥着都是一样的,可以被重写,也可以被子类直接调用,但是一个普通类要继承抽象类,那么必须重写抽象类当中的所有抽象方法。
abstract class Shape {abstract final void methodA();abstract public static void methodB();public void draw() {System.out.println("Shape::draw()");}
}
报错如下:

4.抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用 abstract 修饰。
5.抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类。
6.抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量。
(三)抽象类的作用
抽象类存在的最大意义就是为了被继承,抽象类本身并不能被实例化,要想使用,只能创建该抽象类的子类,然后让子类重写抽象类中的抽象方法。在使用的时候,会多一重编译器的校验。因为直接使用父类的时候就会报错误。
三、接口
(一)接口概念

(二)接口语法规则
public interface 接口名称{
// 抽象方法
//接口中的4中写法
public abstract void method1(); // public abstract 是固定搭配,可以不写
public void method2();
abstract void method3();
void method4();
} Tips:
1. 创建接口时, 接口的命名一般以大写字母 I 开头,2. 接口的命名一般使用 " 形容词 " 词性的单词,3. 阿里编码规范中约定, 接口中的方法和属性不要加任何修饰符号, 保持代码的简洁性。
(三)接口的使用
public class 类名称 implements 接口名称 {...}
注意:子类和父类之间是extends 继承关系,类与接口之间是 implements 实现关系。
让我们看看下面这个代码:
interface IShape {void draw();
}class Cycle implements IShape {@Overridepublic void draw() {System.out.println("圆形");}
}public class Test {public static void main(String[] args) {IShape shape = new Cycle();shape.draw();}
}
运行结果如下:

(四)接口特性
2.接口中每一个方法都是public的抽象方法, 即接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)

3.接口中的方法是不能在接口中实现的,只能由实现接口的类来实现

4.重写接口中方法时,不能使用默认的访问权限

5.接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量
6.接口中不能有静态代码块构造方法

7.接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class
8. 如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类
(五)实现多个接口
有些时候我们需要让一个类同时继承多个父类,但是 Java 实现不了多继承。不过可以通过同时实现多个接口来达到多继承类似的效果。通过类来表示一组动物(通过接口来调用就不用关心引用是谁了)
class Animal {protected String name;public Animal(String name) {this.name = name;}}
interface IFlying {void fly();
}
interface IRunning{void run();
}
interface ISwimming{void swimming();
}
class Bird extends Animal implements IFlying{public Bird(String name) {super(name);}@Overridepublic void fly() {System.out.println(this.name+"正在飞");}
}
class Frog extends Animal implements IRunning,ISwimming{public Frog(String name) {super(name);}@Overridepublic void run() {System.out.println(this.name + "正在跑");}@Overridepublic void swimming() {System.out.println(this.name+"在游泳");}
}
class Duck extends Animal implements IRunning,ISwimming,IFlying{public Duck(String name) {super(name);}@Overridepublic void fly() {System.out.println(this.name+"正在飞");}@Overridepublic void run() {System.out.println((this.name+"正在跑"));}@Overridepublic void swimming() {System.out.println(this.name+"在游泳");}
}
class Roobot implements IRunning{@Overridepublic void run() {System.out.println("机器人在跑");}
}
public class Test {public static void runFunc(IRunning iRunning){iRunning.run();}public static void swimmingFunc(ISwimming iSwimming){iSwimming.swimming();}public static void flyingFunc(IFlying iFlying){iFlying.fly();}public static void main(String[] args) {runFunc(new Duck("鸭子"));runFunc(new Frog("青蛙"));runFunc(new Roobot());}
}
运行结果如下:

通过实现多个接口,可以利用接口来完成需要的功能,通过同时实现多个接口来完成功能。
(六)接口间的继承
interface IA {void funcA();
}
interface IB extends IA {void funcB();
}
//拓展接口的功能 需要对有A和B这俩的方法进行重写
class C implements IB {@Overridepublic void funcB() {}@Overridepublic void funcA() {}
}
(七)使用接口给对象数组排序
我们通过一个例子来加深理解,通过接口对学生年龄进行排序,
学生类代码如下:
package demo4_8;public class Student implements Comparable<Student> {//Comparable接口有局限性,只能进行默认的比较public String name;public int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}//根据年龄比较大小@Overridepublic int compareTo(Student o) {//if(this.age>o.age) {//return 1;//}else if(this.age == o.age) {//return 0;//}else {//return -1;//}return this.age - o.age;}//根据姓名比较大小/* @Overridepublic int compareTo(Student o) {if (this.name.compareTo(o.name) > 0) {return 1;} else if (this.name.compareTo(o.name) == 0) {return 0;} else {return -1;}}*/
}
Test代码如下:
package demo4_8;import java.util.Arrays;public class Test {//Comparable接口的实使用public static void main(String[] args) {Student[] students = new Student[3];students[0] = new Student("zhangsan", 10);students[1] = new Student("lisi", 15);students[2] = new Student("wangwu", 11);System.out.println(Arrays.toString(students));Arrays.sort(students);System.out.println(Arrays.toString(students));}public static void main1(String[] args) {Student student1 = new Student("zhangsan", 18);Student student2 = new Student("lisi", 20);//比较student1和student2/*1.如果student1>student2 返回大于02.如果student1<student2 返回小于03否则返回0相等* */if (student1.compareTo(student2) > 0) {System.out.println("student1 > student2");} else {System.out.println("student1 <= student2");}}
}
运行结果如下:

(八)Clonable 接口和深拷贝
class Person implements Cloneable {public int age;public void eat() {System.out.println("正在吃东西!");}@Overridepublic String toString() {return "Person{" +"age=" + age +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}public class Test {public static void main(String[] args) throws CloneNotSupportedException {Person person = new Person();Person person1 = (Person) person.clone();System.out.println(person1);}
}
运行结果如下:

上面在使用 clone 方法的时候,通过抛出异常,重写异常达到接口的使用。
内存分布如下:

如果把 age 改为 99, 因为 person1 是克隆 person 的,所以person1 的 age 也变成 99 。

因此后面继续对 person1 进行修改,也会改变 age 的值 。

四、抽象类与接口的区别

五、总结
抽象类和接口是 Java 中强大的工具,用于实现抽象和多态性。我们通过了解它们之间的区别和选择条件,为我们后期编写代码提供更多的便利性。以上就是本期的内容,希望小伙伴能收获满满,感谢大家的支持,我们下次再见!
相关文章:
JavaSE:抽象类和接口
目录 一、前言 二、抽象类 (一)抽象类概念 (二)使用抽象类的注意事项 (三)抽象类的作用 三、接口 (一)接口概念 (二)接口语法规则 (三&a…...
发票是扫码验真好,还是OCR后进行验真好?
随着科技的进步,电子发票的普及使得发票的验真方式也在不断演进。目前,我们常见的发票验真方式主要有两种:一种是扫描发票上的二维码进行验真,另一种是通过OCR(Optical Character Recognition,光学字符识别…...
【AIGC调研系列】AIGC+Jmeter实现接口自动化测试脚本生成
AIGC(人工智能生成内容)结合JMeter实现接口自动化测试脚本生成的方法,主要涉及到通过流量收集工具和AIGC技术获取用户操作接口数据,并利用这些数据生成自动化测试脚本的过程。这种方法可以有效提高软件测试的效率和质量[1]。JMete…...
前端|babel升级
问题 项目不支持可选链调用过多的 babel 插件 步骤 基础包 dependencies “react-scripts”: “5.0.1” devDependencies “customize-cra”: “^1.0.0”,“react-app-rewired”: “^2.2.1”, 框架包 dependencies “react”: “16.13.1”,“react-dom”: “16.13.1”, …...
【微服务】spring状态机模式使用详解
一、前言 在很多系统中,通常会涉及到某个业务需要进行各种状态的切换操作,例如在审批流程场景下,某个审批的向下流转需要依赖于上一个状态的结束,再比如电商购物场景中,一个订单的生命周期往往伴随着不同的状态&#…...
【算法刷题day14】Leetcode:144.二叉树的前序遍历、94.二叉树的中序遍历、145.二叉树的后序遍历
文章目录 二叉树递归遍历解题思路代码总结 二叉树的迭代遍历解题思路代码总结 二叉树的统一迭代法解题思路代码总结 草稿图网站 java的Deque 二叉树递归遍历 题目: 144.二叉树的前序遍历 94.二叉树的中序遍历 145.二叉树的后序遍历 解析:代码随想录解析…...
mysql闲谈
如何定位慢查询 1、测试环境压测时,有的接口非常慢,响应时间超过2秒以上。当时系统部署了运维的监控系统Skywalking,在展示报表中可以看到是哪儿个接口慢,可以看到SQL具体执行时间。 2、如果没有类似的监控系统,在Mysq…...
物联网学习1、什么是 MQTT?
MQTT(Message Queuing Telemetry Transport)是一种轻量级、基于发布-订阅模式的消息传输协议,适用于资源受限的设备和低带宽、高延迟或不稳定的网络环境。它在物联网应用中广受欢迎,能够实现传感器、执行器和其它设备之间的高效通…...
【机器学习】数据探索(Data Exploration)---数据质量和数据特征分析
一、引言 在机器学习项目中,数据探索是至关重要的一步。它不仅是模型构建的基础,还是确保模型性能稳定、预测准确的关键。数据探索的过程中,数据质量和数据特征分析占据了核心地位。数据质量直接关系到模型能否从数据中提取有效信息ÿ…...
软件测试(一)--简介+主流技能+分类+模型+流程
一、软件及测试简介 1、软件生产过程 需求产生–需求文档–设计效果图–产品开发–产品测试(测试产品与需求文档是否一致)–部署上线 2、什么是软件测试 使用技术手段验证软件是否满足使用需求。 技术包括:(使用网络技术测试安…...
技术引领,策略升级:腾讯云与你共探数字金融新篇章
引言 2024 年 3 月 27 日下午,在北京腾讯总部,一场关于大模型与数据要素时代数字金融发展的深入讨论火热进行中。【TVP 走进腾讯:大模型与数据要素时代的数字金融发展论坛】是在腾讯二十年发展历程和数字化实践的基础上,进一步探索…...
数据库-root密码丢失的重置方案(win11环境)
当在windows系统中安装的mysql由于操作不当,或者密码遗忘,今天测试了一下,可以用以下方法重置root的密码。 mysqlwindows环境root密码重置问题 在win10/11环境下mysql8密码遗忘后的重置密码方案。 停止mysql服务 查找windows中的mysql服务名称…...
免试生常问的一些问题汇总---专升本学习篇
1.你怎么理解你申请的专业? 答:软件工程室一门涉及软件开发、维护和管理的工程学科。它结合了计算机科学、工程学和管理科学的原理,皆在通过系统化、规范化的方法来开发高质量的软件系统。 1.技术和支持 :软件工程包括编程语言、算法、数据结构、软件设计模式、软件测试、…...
FPGA的就业前景
FPGA(Field-Programmable Gate Array)技术在数字电路设计和嵌入式系统开发方面具有广泛的应用,因此在FPGA领域有着较好的就业前景。 目前,FPGA在通信、计算机、消费电子、汽车、航空航天等行业中得到了广泛应用。随着新一代通信网…...
7.阻塞模式与非阻塞模式
1.阻塞模式 一个线程来处理多个连接显得力不从心 accept等待连接 是一个阻塞方法 read读取SocketChannel中的数据 是一个阻塞方法 /*** 服务端* param args* throws IOException*/public static void main(String[] args) throws IOException {//建立一个缓冲区ByteBuffer b…...
Unity类银河恶魔城学习记录11-10 p112 Items drop源代码
Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili ItemObject_Trigger.cs using System.Collections; using System.Collecti…...
EasyExcel 模板导出excel、合并单元格及单元格样式设置。 Freemarker导出word 合并单元格
xls文件: 后端代码: InputStream filePath this.getClass().getClassLoader().getResourceAsStream(templateFile);// 根据模板文件生成目标文件ExcelWriter excelWriter EasyExcel.write(orgInfo.getFilename()).excelType(ExcelTypeEnum.XLS).withTe…...
炫我科技:云渲染领域的佼佼者
随着数字化时代的来临,云渲染技术正逐渐成为影视、游戏、动画等创意产业的重要支柱。在这一领域中,炫我科技凭借其卓越的技术实力、优质的服务以及不断创新的精神,已然成为了云渲染行业的佼佼者。 炫我科技自成立之初,便以打造高…...
VsCode正确解决vue3+Eslint+prettier+Vetur的配置冲突
手把手教你VsCode正确解决vue3EslintprettierVetur的配置冲突 VsCode正确解决vue3EslintprettierVetur的配置冲突Eslint文档查看和修改规则:step1:首先快速浏览下规则简要setp2: ctrlF 搜索你要配置规则的英文名,例如attributesetp3: 修改配置…...
计算机网络—VLAN 间路由配置
目录 1.拓扑图 2.实验环境准备 3.为 R3 配置 IP 地址 4.创建 VLAN 5.配置 R2 上的子接口实现 VLAN 间路由 6.配置文件 1.拓扑图 2.实验环境准备 配置R1、R3和S1的设备名称,并按照拓扑图配置R1的G0/0/1接口的IP地址。 [Huawei]sysname R1 [R1]interface Giga…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...
无需布线的革命:电力载波技术赋能楼宇自控系统-亚川科技
无需布线的革命:电力载波技术赋能楼宇自控系统 在楼宇自动化领域,传统控制系统依赖复杂的专用通信线路,不仅施工成本高昂,后期维护和扩展也极为不便。电力载波技术(PLC)的突破性应用,彻底改变了…...
基于 HTTP 的单向流式通信协议SSE详解
SSE(Server-Sent Events)详解 🧠 什么是 SSE? SSE(Server-Sent Events) 是 HTML5 标准中定义的一种通信机制,它允许服务器主动将事件推送给客户端(浏览器)。与传统的 H…...
