Java重修第五天—面向对象3
通过学习本篇文章可以掌握如下知识
1、多态;
2、抽象类;
3、接口。
之前已经学过了继承,static等基础知识,这篇文章我们就开始深入了解面向对象多态、抽象类和接口的学习。
多态
多态是在继承/实现情况下的一种现象,表现为:对象多态和行为多态。
对象多态
指的是一个人可以有多个身份,例如可以是学生,老师和消防员

行为多态
指的是不同身份的人都可以跑,但是跑的行为不同,这里的行为包括速度、姿态等等都可以称之为行为。对应到代码里面就是,run方法的实现逻辑不同。注意现实或者文字描述如何对应到代码。

代码验证
// 分类
public class People {public void run(){System.out.println("人可以跑");}
}class Student extends People{@Overridepublic void run(){System.out.println("学生可以跑的很快");}
}class Teacher extends People{@Overridepublic void run(){System.out.println("老师可以跑有点慢~");}
}
结果

还记得上一篇文章讲的方法的覆盖吗?方法能覆盖的前提是父类对象也有相同的方法。因此p1想要调用run方法的前提是Person类有run方法,否则会报错。

到此相信你应该对动态有一定的认识了吧。
那么仅仅认识这些还是不够的,下来讲对多态的一个全新的用法。
方法的入参是父类,则可以接收父类和子类对象
代码验证
public class Test {public static void main(String[] args) {People s1 = new Student();People p1 = new People();People t1 = new Student();//方法的入参是父类,则可以接收父类和子类对象go(p1);go(s1);go(t1);}public static void go( People p) {p.run();}
}
结果验证

final
在java中final是常量的意思,相对比较简单,其功能也比较用以验证。因此就直接将其功能结论记录如下。
总结

抽象类
在java中存在一个关键词:abstract(抽象) 用来修饰类和成员方法。
被修饰的类叫做抽象类,被修饰方法叫做抽象方法。

特点:
- 抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类。
- 抽象类不能创建对象,一般来说抽象类往往作为父类。
- 一个类A继承抽象类,必须重写抽象类的全部抽象方法,否则类A也被定义为抽象类。
这些特点可以用代码验证,由于过于简单这里就不再阐述。
抽象类的场景和好处
之前学习到了多态,可以配合抽象类一起使用,
- 父类知道子类想要做某个行为,但是每个子类的实现情况不一样,因此父类可以定义为抽象类,交给子类重写方法,可以更方便的支持多态。
例如:

代码实现

抽象类的应用—模板模式
学习完模板模式,你应该总结出,模板模式解决了什么问题,解决思路是怎么样的。
它为解决方法中存在重复代码的问题。

如何实现?
1、定义一个抽象类
2、在里面定义两个方法
一个是模板方法:把相同代码放里面去。
一个是抽象方法:具体实现交给子类完成。
场景1:写作文:
第一段是相同的
最后一段也是相同的
只有最后一段是不同的。
场景2:移动支付
支付前的校验
不同的支付方式(支付宝,微信,银行卡,xxx)
支付后的操作。
public abstract class People {public void write(){System.out.println("\t\t\t《看书》");System.out.println("周六作业看书xxxxxx");System.out.println(writeMain());System.out.println("终于看完了");}public abstract String writeMain();
}public class Student extends People{@Overridepublic String writeMain() {return "我是学生我爱看书xxxxx";}
}public class Teacher extends People{@Overridepublic String writeMain() {return "我是老师,我要看名著";}
}// 测试
public class Test {public static void main(String[] args) {People s1 = new Student();s1.write();System.out.println("===============");People t1 = new Teacher();t1.write();}}
测试结果

接口
java提供了关键字interface,用这个关键字可以定义一个特殊的结构:接口

在jdk1.8之前,接口中只能定义成员变量和抽象方法


接口的好处:
1、弥补了类单继承的不足,一个类可以同时实现多个接口
2、让程序可以面向接口编程,这样程序更加灵活。(多态)
代码实现
public class Test {public static void main(String[] args) {}
}class A extends Student implements Driver, Singer{@Overridepublic void drive() {System.out.println("我继承了student,并且会开车");}@Overridepublic void song() {System.out.println("我继承了student,并且会唱歌");}
}class Student{}interface Driver{void drive();
}interface Singer{void song();
}
总结
继承就像在说你是谁,你来自哪里哪一类。
接口就好像在说你会什么,有什么能力,你被贴了什么标签,例如歌手标签,
综合案例

代码实现
// 测试类
public class Test {public static void main(String[] args) {ClassManage classManage = new ClassManage(new StudentOperatorImpl2());ArrayList<Student> students = classManage.getStudents();students.add(new Student("迪丽热巴",false,99));students.add(new Student("古力娜扎",false,100));students.add(new Student("马尔扎哈",true,95));students.add(new Student("卡尔扎巴",true,92));classManage.studentOperator.printAllInfo(classManage.getStudents());classManage.studentOperator.printAverageScore(classManage.getStudents());}
}
学生类
public class Student {private String name;private boolean sex;private double score;public Student() {}public Student(String name, boolean sex, double score) {this.name = name;this.sex = sex;this.score = score;}public String getName() {return name;}public void setName(String name) {this.name = name;}public boolean isSex() {return sex;}public void setSex(boolean sex) {this.sex = sex;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}
}
班级管理类
public class ClassManage {private ArrayList<Student> students;StudentOperator studentOperator;public ClassManage(StudentOperator operator) {this.studentOperator = operator;this.students = new ArrayList<>(10);}public void addStudent(Student student){students.add(student);}public ArrayList<Student> getStudents() {return students;}
}
操作接口
public interface StudentOperator {void printAllInfo(ArrayList<Student> students);void printAverageScore(ArrayList<Student> students);
}
接口实现类1
public class StudentOperatorImpl1 implements StudentOperator {@Overridepublic void printAllInfo(ArrayList<Student> students) {System.out.println("--------全班全部学生信息如下----------");students.forEach(student -> {System.out.println("姓名:" + student.getName());System.out.println("性别:" + student.isSex());System.out.println("成绩:" + student.getScore());});}@Overridepublic void printAverageScore(ArrayList<Student> students) {System.out.println("-------全班学生平均成绩如下-----------");double sum = 0.0;for (Student student : students) {sum += student.getScore();}System.out.println("全班的平均成绩为:" + sum / students.size());}
}
接口实现类2
public class StudentOperatorImpl2 implements StudentOperator {@Overridepublic void printAllInfo(ArrayList<Student> students) {System.out.println("--------全班全部学生信息如下----------");int male = 0;int female = 0;for (Student student : students) {System.out.println("姓名:" + student.getName());System.out.println("性别:" + student.isSex());System.out.println("成绩:" + student.getScore());if (student.isSex()) {male++;} else {female++;}}System.out.println("男生人数:" + male + ", 女生人数:" + female);}@Overridepublic void printAverageScore(ArrayList<Student> students) {double max = 0.0;double min = 101.0;double sum = 0.0;for (Student student : students) {max = Math.max(max, student.getScore());min = Math.min(min, student.getScore());sum += student.getScore();}System.out.println("全班的平均成绩为:" + ((sum - max - min) / (students.size() - 2)));}
}
为什么实现的这么复杂呢?因为这样设计的好处就在于可以仅仅改变下图这一个地方就可以改变不同的实现方案。

JDK8以后接口新增的内容
默认方法:如果接口只有默认方法,那么实现类就可以直接使用。
public class Test2 {public static void main(String[] args) {AImpl a1 = new AImpl();a1.test1();}
}interface A{// 新增的默认方法。// 必须使用default 修饰public default void test1(){System.out.println("===默认方法===");}
}class AImpl implements A{}
结果展示

私有方法
jdk9以后才有的新特性,私有方法和默认方法能够访问私有方法。

静态方法
必须使用static修饰,直接使用接口调用。

总结

有时候你会迷茫学这些干嘛?这些是java的基础特性,就是要背诵或者熟练使用的,就好像数学中懂了加法和乘法才会数学运算一样,因此需要熟练掌握。
相关文章:
Java重修第五天—面向对象3
通过学习本篇文章可以掌握如下知识 1、多态; 2、抽象类; 3、接口。 之前已经学过了继承,static等基础知识,这篇文章我们就开始深入了解面向对象多态、抽象类和接口的学习。 多态 多态是在继承/实现情况下的一种现象…...
【征稿进行时|见刊、检索快速稳定】2024年经济发展与旅游管理国际学术会议(ICEDTM 2024)
【征稿进行时|见刊、检索快速稳定】2024年经济发展与旅游管理国际学术会议(ICEDTM 2024) 2024 International Conference Economic Development and Tourism Management(ICEDTM 2024) 一、【会议简介】 ICEDTM 2024将围绕"旅游管理”“经济发展”的最新研究领域ÿ…...
瑞_Java开发手册_(四)安全规约
🙊前言:本文章为瑞_系列专栏之《Java开发手册》的安全规约篇。由于博主是从阿里的《Java开发手册》学习到Java的编程规约,所以本系列专栏主要以这本书进行讲解和拓展,有需要的小伙伴可以点击链接下载。本文仅供大家交流、学习及研…...
Docker 安全必知:最佳实践、漏洞管理与监控策略
容器安全是实施和管理像 Docker 这样的容器技术的关键方面。它包括一组实践、工具和技术,旨在保护容器化应用程序及其运行的基础架构。在本节中,我们将讨论一些关键的容器安全考虑因素、最佳实践和建议。 容器隔离 隔离对于确保容器化环境的强大性和安全…...
【Flutter】多线程
Flutter 作为一个跨平台的UI库,前面的Flutter 架构有涉及到,Flutter 架构中的运行的多个线程。那么最为一个Flutter开发者,我们如何创建线程呢 多线程 上述我们提及到了,架构层涉及的多线程问题。比如说 主线程, 平台线程&#x…...
STM32-实时时钟RTC-1
...
node(express.js创建项目)+连接mysql数据库
1.node npm的安装 2.express的安装 全局安装:npm install express -gnpm install -g express-generator// ps: 4.0版本把generator分离出来了,需要单独安装3.创建express项目 express 项目名称 cd 项目名称 npm install npm start4.项目中安装数据库 npm install…...
【FLV】记录 H.264的解析
参考 FLV 文件格式分析 知乎大神的FLV文件格式分析。 FLV 首先下发9个字节的FLV 头 -2024-01-08 11:38:29.698 INFO [32196] [evplayer_client_main@153] player clinet run … 2024-01-08 11:38:29.702 INFO [2276] [evplayer_client_main::<lambda_1>::operator ()@14…...
nodejs+vue+ElementUi音乐分享社交网站77l8j
本文介绍的系统主要分为两个部分:一是前台界面:用户通过注册登录可以实现音乐播放、新闻浏览、留言评论等功能;另一个是后台界面:音乐网站管理员对用户信息进行管理,上传更新音乐资源,发布最新音乐资讯等功…...
进销存+小程序商城:实现批发零售企业的互联网转型与管理升级
在当今互联网高速发展的时代,越来越多的批发零售企业开始开始考虑转型。在这个行业中,企业要想取得更好的发展,就要积极地拥抱互联网。专属的订货商城小程序是企业转型的第一步。通过将进销存与订货商城一体化,企业可以更好地满足…...
Tomcat解压打包文件和并部署
一、文件压缩和上传解压 1.本地打包好dist.tar.gz文件 2.通过xftp拖拽上传到知道文件夹下,或者通过命令: cp dist.tar.gz /path/to/destination/folder注:将dist.tar.gz复制到 /path/to/destination/folder文件夹下,该文件夹只是举个例子怎么复制和解压! 3.进入/path/…...
JDK17
JDK 17是Java开发工具包(Java Development Kit)的一个版本。JDK是用于开发和运行Java应用程序的软件包,它包含了编译器、调试器、运行时环境和其他一些实用工具。JDK 17是Java的最新版本,它提供了许多新的功能、增强和改进。 使用…...
使用Docker运行SRS Stack
SRS Stack | SRS (ossrs.net) Docker 推荐使用Docker运行SRS Stack: docker run --restart always -d -it --name srs-stack -v $HOME/data:/data \-p 2022:2022 -p 2443:2443 -p 1935:1935 -p 8000:8000/udp -p 10080:10080/udp \registry.cn-hangzhou.aliyun…...
git安装教程 Windows 附安装包链接
Git是一款分布式源代码管理工具(版本控制工具) 。 git的作用 当你需要做一个大工程的时候,文件的管理无疑是非常庞大的工作,因为你需要不断的修改更新文件内容,同时可能还要保留旧版本保证可以复原,这样就需要备份多个版本的文件…...
TensorRT(C++)基础代码解析
TensorRT(C)基础代码解析 文章目录 TensorRT(C)基础代码解析前言一、TensorRT工作流程二、C API2.1 构建阶段2.1.1 创建builder2.1.2 创建网络定义2.1.3 定义网络结构2.1.4 定义网络输入输出2.1.5 配置参数2.1.6 生成Engine2.1.7 保存为模型文件2.1.8 释放资源 2.2 运行期2.2.1…...
如何查询MySQL中的树型表
在 MySQL 中查询树型表(即具有层级结构的表)可以使用递归查询或者使用嵌套集模型。下面分别介绍这两种方法: 递归查询:递归查询是通过自连接来实现的,可以使用 WITH RECURSIVE 关键字进行递归查询。假设有一个 catego…...
Programming Abstractions in C阅读笔记:p246-p247
《Programming Abstractions in C》学习第68天,p246-p247总结,总计2页。 一、技术总结 本章通过“the game of nim(尼姆游戏)”,这类以现实生活中事物作为例子进行讲解的情况,往往对学习者要求比较高,需要学习者具备…...
智能寻迹避障清障机器人设计(电路图附件+代码)
附 录 智能小车原理图 智能小车拓展板原理图 智能小车拓展板PCB 智能小车底板PCB Arduino UNO原理图 Arduino UNO PCB 程序部分 void Robot_Traction() //机器人循迹子程序{//有信号为LOW 没有信号为HIGHSR digitalRead(SensorRight);//有信号表明在白…...
设计模式-- 3.适配器模式
适配器模式 将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 角色和职责 请求者(client):客户端角色,需要使用适配器的对象,不需要关心适配器内部的实现,…...
设计一个简单的规则引擎
👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家📕系列专栏:Spring原理、JUC原理、Kafka原理、分布式技术原理、数据库技术🔥如果感觉博主的文章还不错的…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
