Java零基础学习Day10——面向对象高级

一.认识final

1.含义

final关键字是最终的意思,可以修饰:类,方法,变量

修饰类:该类被称为最终类,特点是不能被继承

修饰方法:该方法被称为最终方法,特点是不能被重写

修饰变量:该变量有且仅能被赋值一次

final修饰静态变量,这个变量今后被称为常量,可以记住一个固定值,并且程序中不能修改了,通常这个值作为系统的配置信息,作为共享值所有人都可以用

常量的名称:建议全部大写,多个单词用下划线进行连接

注:final修饰实例变量一般情况下没有意义!!!

2.final修饰变量的注意

final修饰基本类型的变量,变量存储的数据不能被改变

final修饰引用类型的变量,变量存储的地址不能被改变,但地址所指向的对象的内容可以被改变

final int[] arr = {11,22,33,44};
//arr = new int[]{33,44,55};  //第二次赋值,报错
arr[2]=90;//不报错,可以修改

二.常量

1.含义

使用了static final修饰的成员变量就被称为常量

作用:常用于记录系统的配置信息

注:命名规范建议使用大写英文字母,多个单词使用下划线连接起来

2.优点

代码可读性更好,可维护性更好

程序编译后,常量会被“宏(全部)替换”:出现常量的地方全部会被替换成其记住的字面量,这样可以保证使用常量和直接用字面量的性能是一样的

三.单例类(设计模式)

注:这个属于系统架构师层面的技术

1.什么是设计模式

一个问题通常有n种解法,其中肯定有一种解法是最优的,这个最优的解法被人总结出来了,就称之为设计模式

2.关于设计模式,主要学什么

解决什么问题:确保某个类只能创建一个对象

怎么写

3.单例设计模式

作用:确保某个类只能创建一个对象

写法步骤:

  • 把类的构造器私有:确保单例类对外不能创建太多对象,单例才有可能性
  • 定义一个静态变量:用于基本本类的一个唯一对象
  • 提供一个静态方法:用于返回对象
//单例类
public class A{//2.定义一个类变量记住类的一个变量private static A a = new A();//1.私有构造器private(){}//3.定义一个类方法返回对象public static A getobject(){return a;}
}
public static A a = new A();//这两句其实是相同的意思,上面的 A就是跟下面的 int一样代表数据类型//new A()代表的是对象public static int a1 = 20;

 4.饿汉式单例的特点

在获取类的对象时,对象已经创建好了

5.单例有啥应用场景,有啥好处

任务管理器对象、获取运行时对象,避免浪费内存及无效资源浪费

6.懒汉式单例类

真正要用对象时,才开始创建对象

写法:

  • 把类的构造器私有
  • 定义一个静态变量用于存储对象
  • 提供一个静态方法,保证返回的是同一个对象
public class B{//2.定于一个类变量用于存储对象private static B b;//null//1.单例必须私有构造器private B(){}//3.提供一个类方法返回类的的一个对象public static B getobject(){if(b == null){b = new B();}return b;}
}

四.枚举类

1.枚举类的写法

修饰符enum枚举类名{名称1,名称2,....;其他成员...
}public enum A{X,Y,Z;...
}

2.枚举类的特点

  • 枚举类中的第一行,只能写枚举类的对象名称,且要用逗号隔开
  • 这些名词,本质是常量,每个变量都记住了枚举类的一个对象
  • 枚举都是最终类,不可以被继承,枚举类都是继承java.lang.Enum类的
  • 枚举类的构造器都是私有的(写不写都只能时私有的),因此,枚举类对外不能创建对象
  • 编译器为枚举类新增了几个方法
  • 枚举是一种特殊类
public static A[] values();//将所有枚举的对象放到数组中public static A valueOf(java.lang.String);
//通过枚举对象的名字去定位某个枚举对象a1.name()可以拿枚举对象 的名称
a1.ordinal()可以拿枚举对象 的索引

3.枚举类的常见应用场景

枚举类很适合做信息分类和标志

package com.itheima;public class Test {public static void main(String[] args) {//目标:掌握枚举类的应用场景,信息的分类和标志//需求:模拟上下左右移动图片move(Direction.UP);}public static void move(Direction direction){switch (direction){case UP://可直接写UP,因为枚举类中定义的常量值都是UP,Direction可以省略System.out.println("向上移动");break;case Down:System.out.println("向下移动");break;case Left:System.out.println("向左移动");break;case Right:System.out.println("向右移动");break;default:System.out.println("无效指令");}}
}
package com.itheima;public enum Direction {UP,Down,Left,Right;}

五.抽象类

1.含义

在Java中有一个关键字叫:abstract(抽象),用这个可以修饰类、成员方法

abstract修饰类,这个类就是抽象类

abstract修饰方法,这个方法就是抽象方法

2.语法

修饰符 abstract class 类名{修饰符 abstract 返回值类型 方法名称(形参列表);
}public abstract class A{//抽象方法:必须abstract修饰,只有方法签名,不能有方法体,意味着不能有大括号public abstract void test();
}

3.抽象类的注意事项、特点

抽象类中不一定要有抽象方法,有抽象方法的类必须是抽象类

类有的成员:成员变量、方法、构造器、抽象类都可以有

抽象类最主要的特点是:抽象类不能创建对象,仅作为一种特殊的父类,让子类继承并实现

一个类继承抽象类,必须重写玩抽象类的全部抽象方法,否则这个类也必须定义成抽象类

注:在实际开发中,会全部重写抽象方法,而不是再定义成抽象类,这样就可以自己创建对象

方法:Alt键+回车,即可全部重写

4.使用抽象类的优点(非必须)

父类知道每个子类都要做某个行为,但每个子类都要做到情况不一样。父类就定义成抽象方法,交给子类去重写实现,我们设计这样的抽象类,就是为了更好的支持多态

注:以后要做关于面向对象的设计时,如果所有子类都要做出功能,每个子类的功能又各不相同,即可把这个父类定义成抽象类和抽象方法

5.抽象类使用场景之一(模板方法设计模式)

提供给一个方法作为某类功能的模板,模板方法封装了每个实现步骤,但允许子类提供特定步骤的实现

模板方法设计模式:提高代码的复用、并简化子类设计

写法:

1.定义一个抽象类

2.在里面定义两个方法

  • 一个是模板方法:把共同的实现步骤放里面去
  • 一个是抽象方法:不确定的实现步骤,交给具体的子类来完成

注:建议使用final关键字修饰模板方法,控制方法不被重写

六.接口

1.含义

Java提供了一个关键字interface定义出接口

public interface 接口名{//成员变量(常量)//成员方法(抽象方法)
}

在JDK 8 之前,接口中只能定义常量和抽象方法。

在接口中定义常量可以省略public static final 不写,默认自动添加,抽象方法同理。

作用:接口是用来被类实现的,实现接口的类称为实现类,一个类可以同时实现多个接口。

修饰符 class 实现类类名 implements 接口1,接口2,接口3,....{//实现类实现多个接口,必须重写完全部接口的全部抽象方法,否则实现需要定义成抽象类
}

2.注意

接口不能创建对象。

3.接口的优点

弥补了类单继承的不足,一个类同时可以实现多个接口,使类的角色更多,功能更强大。

让程序可以面向接口编程,这样程序员就可以灵活方便的切换各种业务实现(更有利于程序的解耦合)。 

4.接口案例:学生信息系统

package com.iteheima.interface1;public interface ClassDataInter {void printAllStudentInfos();void printAverageScore();
}

ClassDateinter.java

package com.iteheima.interface1;public class Text {//把这个可以看作A公司提供的模板,其他两个实现类功能由另外公司完成,这就是协作开发public static void main(String[] args) {//目标:完成接口的小案例//1.定义学生类,创建学生对象,封装数据,才能交给别人进行调用//2.准备学生数据,人为制造数据Student[] allstudents = new Student[10];//创建数组allstudents并设计容量为10allstudents[0] = new Student("小王",'男',90.5);allstudents[1] = new Student("小张",'女',80.5);allstudents[2] = new Student("小李",'男',70.5);allstudents[3] = new Student("小赵",'女',60.5);allstudents[4] = new Student("小孙",'男',50.5);allstudents[5] = new Student("小周",'女',40.5);allstudents[6] = new Student("小吴",'男',30.5);allstudents[7] = new Student("小郑",'女',20.5);allstudents[8] = new Student("小王",'男',10.5);allstudents[9] = new Student("小王",'女',90.5);//3.提供两套业务实现方案,支持灵活切换(解耦合)//——定义一个接口(规范思想):必须完成打印全班学生信息,打印平均分//——定义第一套实现类,实现接口:完成打印全班学生信息,实现打印平均分//——定义第二套实现类,实现接口:实现打印学生信息(男女人数),实现打印平均分(去掉最高分和最低分)ClassDataInter cdi = new ClassDataInterImpl1(allstudents);//接口创建对象不能用new,而是用实现类//上面这里就已经实现了解耦,如果要换实现类,只要换一个实现类,接口调用方法不变cdi.printAllStudentInfos();cdi.printAverageScore();

Text.java

package com.iteheima.interface1;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data//构建get和set方法
@NoArgsConstructor//无参构造器
@AllArgsConstructor//有参构造器
class Student {//创建学生类,封装数据private String name;private char sex;private double score;
}

Student.java

package com.iteheima.interface1;public class ClassDataInterImpl1 implements ClassDataInter{//类名[] 变量名(声明数组变量)private Student[] students;//创建数组记住下面送进来的全部学生信息public ClassDataInterImpl1(Student[] students) {//用有参构造器接收学生信息this.students = students;//将外部传入的数组赋给成员变量students}@Overridepublic void printAllStudentInfos() {System.out.println("所有学生的信息为:");for (int i = 0; i < students.length; i++) {Student student = students[i];System.out.println(student.getName() + " " + student.getSex() + " " + student.getScore());}}@Overridepublic void printAverageScore() {double sum = 0;for (int i = 0; i < students.length; i++) {Student student = students[i];sum += student.getScore();}System.out.println("平均分是:" + sum / students.length);}
}

ClassDateInterImpl1.java

package com.iteheima.interface1;
//——定义第二套实现类,实现接口:实现打印学生信息(男女人数),实现打印平均分(去掉最高分和最低分)
public class ClassDataInterImpl2 implements ClassDataInter{private Student[] students;public ClassDataInterImpl2(Student[] students) {this.students = students;}@Overridepublic void printAllStudentInfos() {int maleCount = 0;//男生人数for (int i = 0; i <students.length; i++) {Student student = students[i];if (student.getSex() == '男') {maleCount++;}System.out.println(student.getName() + " " + student.getSex() + " " + student.getScore());System.out.println("男性学生数量为:" + maleCount);System.out.println("女性学生数量为:" + (students.length - maleCount));}}@Overridepublic void printAverageScore() {System.out.println("平均分如下:");Student s1 = students[0];//这边sum,max,min不能直接设计成0,万一值为0,那么后面求平均数就会出错double sum = s1.getScore();double max = s1.getScore();double min = s1.getScore();for (int i = 0; i < students.length; i++) {Student student = students[i];sum += student.getScore();if (student.getScore() > max) {max = student.getScore();} else if (student.getScore() < min) {min = student.getScore();}}System.out.println("最高分是:" + max);System.out.println("最低分是:" + min);System.out.println("平均分是:" + (sum-min-max) / (students.length-2));}
}

ClassDateInterImpl2.java

5.JDK开始,接口新增的三种方法

package com.iteheima.interface1.interface4;public interface A {//1.默认方法(普通实例方法):必须加default关键字修饰//默认会用public修饰//使用接口的实现类的对象来进行调用default void go(){System.out.println("==go方法执行==");run();}//2.私有方法:必须加private关键字修饰//使用接口中的其他实例方法来进行调用private void run(){System.out.println("==run方法执行==");}//3.静态方法:必须加static关键字修饰//只能使用当前接口名来调用static void show(){System.out.println("==show方法执行==");}}

A.java

package com.iteheima.interface1.interface4;public class Text {//目标:搞清楚接口新增的三种方法,并理解其好处public static void main(String[] args) {AImpl a = new AImpl();//创建对象a.go();//用实现类来进行调用}
}
//创建实现类AImpl
class AImpl implements A{}

Text.java

好处:

增强了接口的能力,便于项目的扩展和维护

why:新增的这些方法可以直接在接口中定义好具体的方法,新增功能时可以不用重新写方法

6.接口的注意事项

  • 接口与接口可以多继承:一个接口可以同时继承多个接口
  • 一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承,也不支持多实现
  • 一个类继承了父类,又同时实现了接口,如果父类中和接口有同名的默认方法,实现类会优先用父类的
  • 一个类实现了多个接口,如果多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可

七.接口和抽象类的区别对比

1.相同点

  • 多是抽象形式,都可以由抽象方法,都不能创建对象
  • 都是派生子类形式:抽象类是被子类继承使用,接口是被实现类实现
  • 一个类继承抽象类,或者实现接口,都必须重写抽象方法,否则自己成为抽象类
  • 都能支持的多态,都能实现解耦合

2.不同点

  • 抽象类中可以定义类的全部普通成员,接口只能定义常量,抽象方法(JDK8新增的三种方法)
  • 抽象类只能被类单继承,接口可以被类多实现
  • 一个类继承抽象类就不能再继承其他类,一个类实现了接口,还可以继承其他类或者其他接口
  • 抽象类体现模板思想:更利于做父类,提高代码的复用性(最佳实践)
  • 接口更适合做功能的解耦合:解耦合性更强更灵活(最佳实践)

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

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

相关文章

Qt中解析JSON文件

Qt中解析JSON文件 在Qt中解析JSON字符串主要有两种方式&#xff1a;使用QJsonDocument类或使用QJsonDocument结合QVariant。以下是详细的解析方法&#xff1a; 使用QJsonDocument&#xff08;推荐&#xff09; 这种方式的主要相关类如下&#xff1a; QJsonDocument: QJsonDocum…

深度解析HTTPS:从加密原理到SSL/TLS的演进之路

在互联网时代,数据安全已成为不可忽视的基石。当我们在浏览器地址栏看到"https://"前缀和那把小小的绿色锁图标时,意味着正在进行一场受保护的通信。但这层保护究竟是如何实现的?HTTPS、SSL和TLS之间又存在着怎样的联系与区别?本文将深入剖析这些技术细节,带你全…

Flutter 官方 LLM 动态 UI 库 flutter_genui 发布,让 App UI 自己生成 UI

今日&#xff0c;Flutter 官方正式发布了它们关于 AI 大模型的 package 项目&#xff1a; genui &#xff0c;它是一个非常有趣和前沿的探索类型的项目&#xff0c;它的目标是帮助开发者构建由生成式 AI 模型驱动的动态、对话式用户界面&#xff1a; 也就是它与传统 App 中“写…

Redis常用数据结构及其底层实现

Redis常用数据结构主要有String List Set Zset Hash BitMap Hyperloglog Stream GeoString:Redis最常用的一种数据结构,Sting类型的数据存储结构有三种int、embstr、raw1.int:用来存储long以下的整形embstr raw 都是用来存字符串&#xff0c;其中小于44字节的字符串用embstr存 …

O3.4 opencv图形拼接+答题卡识别

一图形拼接逻辑导入必要的库pythonimport cv2 import numpy as np import sys导入cv2库用于图像处理&#xff0c;numpy库用于数值计算&#xff0c;sys库用于与 Python 解释器进行交互&#xff0c;例如退出程序。定义图像显示函数def cv_show(name, img):cv2.imshow(name, img)c…

SQL注入常见攻击点与防御详解

SQL注入是一种非常常见且危险的Web安全漏洞。攻击者通过将恶意的SQL代码插入到应用程序的输入参数中&#xff0c;欺骗后端数据库执行这些非预期的命令&#xff0c;从而可能窃取、篡改、删除数据或获得更高的系统权限。以下是详细、准确的SQL注入点分类、说明及举例&#xff1a;…

EKSPod 资源利用率配置修复:从占位符到完整资源分析系统

概述 在 Kubernetes 集群管理过程中,资源利用率的监控和优化是保证应用性能和成本效益的关键环节。近期,我们对 EKSPod 管理界面的资源利用率显示功能进行了全面修复,将原先简单的占位符文本升级为完整的资源分析系统。本文将详细介绍这次修复的背景、方案、实现细节和最终…

Linux内核(架构)

文章目录Linux内核架构概述核心子系统详解1、进程管理2、内存管理3、虚拟文件系统(VFS)4、设备驱动模型掌握Linux内核核心技术阶段1&#xff1a;基础准备阶段2&#xff1a;内核基础阶段3&#xff1a;深入子系统阶段4&#xff1a;高级主题&#xff08;持续学习&#xff09;调试和…

基于数据挖掘的单纯冠心病与冠心病合并糖尿病的证治规律对比研究

标题:基于数据挖掘的单纯冠心病与冠心病合并糖尿病的证治规律对比研究内容:1.摘要 背景&#xff1a;冠心病和冠心病合并糖尿病在临床上较为常见&#xff0c;且二者在证治方面可能存在差异&#xff0c;但目前相关系统研究较少。目的&#xff1a;对比基于数据挖掘的单纯冠心病与冠…

即梦AI快速P图

原图&#xff1a; 模型选择3.0效果比较好&#xff0c;提示词“根据提供图片&#xff0c;要求把两边脸变小&#xff0c;要求把脸变尖&#xff0c;要求眼妆变淡&#xff0c;眼睛更有神&#xff0c;要求提亮面部肤色要求面部均匀&#xff0c;面部要磨皮!鼻头高光和鼻翼两边阴影变淡…

【办公类-109-04】20250913圆牌卡片(接送卡被子卡床卡入园卡_word编辑单面)

背景需求: 为了发被子,我做了全校批量的圆形挂牌,可以绑在“被子包”提手上,便于再操场上发放被子时,很多老师可以协助根据学号发放。 https://blog.csdn.net/reasonsummer/article/details/149755556?spm=1011.2415.3001.5331https://blog.csdn.net/reasonsummer/arti…

Shoptnt 促销计算引擎详解:策略模式与责任链的完美融合

在电商系统中&#xff0c;促销计算是业务逻辑最复杂、变更最频繁的模块之一。它不仅需要处理多种促销类型&#xff08;满减、折扣、优惠券等&#xff09;&#xff0c;还要管理它们之间的优先级和互斥关系。 Shoptnt 设计了一套基于 策略模式 (Strategy Pattern) 和 责任链模式…

【HTTP 请求格式】从请求行 到 请求体

引言 在前后端开发中&#xff0c;前端和后端之间的交互主要依赖于 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;。HTTP 是互联网通信的基础&#xff0c;它定义了客户端&#xff08;通常是浏览器或App&#xff09;和服务器之间如何交换数…

【自记】SQL 中 GROUPING 和 GROUPING SETS 语句的案例说明

我们用一个生活中的例子来理解&#xff0c;比如你开了家小超市&#xff0c;想统计「销售额」&#xff0c;但需要从多个角度看&#xff08;比如按 “日期 商品”、“仅日期”、“仅商品”、“整体总销售额”&#xff09;。假设你的销售数据长这样&#xff08;简化版&#xff09…

C语言第五课:if、else 、if else if else 控制语句

C语言第五课&#xff1a;if、else 、if else if else 控制语句if else 、if else if else 联合使用编程快速学习平台if else 、if else if else 联合使用 代码示列 #include <stdio.h> int main(){//设置中文编码输出到控制台system("chcp 65001");//今天星…

七彩喜智慧养老:用科技温暖晚年,让关爱永不掉线

“当银发潮遇见科技力&#xff0c;养老方式正在发生一场静悄悄的变革。”你有没有想过&#xff1a;当父母年迈独居时&#xff0c;如何确保他们的安全&#xff1f;当老人突然摔倒&#xff0c;如何第一时间获得救助&#xff1f;当慢性病需要长期管理&#xff0c;如何避免频繁奔波…

window显示驱动开发—为头装载和专用监视器生成自定义合成器应用(二)

显示相关的 API 的比较 API用途和目标受众DisplayInformation用于检索 CoreWindow 的呈现和布局属性。HdmiDisplayInformation用于枚举和设置受限模式集的仅限 Xbox 的 API。 高度专用于 Xbox 媒体应用方案。DisplayMonitor用于查询物理监视器设备的属性。 不公开有关操作系统…

Linux 高性能 I/O 事件通知机制的核心系统调用—— `epoll_ctl`

epoll 是 Linux 上处理大量文件描述符 I/O 事件的高效模型&#xff0c;而 epoll_ctl 则是你用来指挥 epoll 实例&#xff08;epoll instance&#xff09;的“遥控器”&#xff0c;负责向它添加、修改或删除需要监视的文件描述符&#xff08;FD&#xff09;及其感兴趣的事件。1.…

mysql 必须在逗号分隔字符串和JSON字段之间二选一,怎么选

如果必须在逗号分隔字符串和JSON字段之间二选一&#xff0c;那么 JSON字段是明显更好的选择。以下是详细的对比分析&#xff1a;对比结论&#xff08;直接看这里&#xff09;方面JSON字段逗号分隔字符串胜出方查询能力✅ 丰富的JSON函数支持❌ 只能使用LIKE模糊查询JSON数据验证…

DPI和DIP的区别

DPI 和 DIP 是两个在计算机图形和移动开发领域常见的术语&#xff0c;它们都与屏幕显示和尺寸有关&#xff0c;但含义和用途不同。 DPI (Dots Per Inch) 定义&#xff1a;DPI 的全称是 Dots Per Inch&#xff0c;即每英寸点数。它是一个衡量物理密度的单位&#xff0c;表示在…