JavaSE

文章目录

day01之Java基础入门

一、Java介绍(了解)

1.Java背景

● Java是美国sun公司1995年推出的计算机高级编程语言。
● Java之父:詹姆斯·高斯林
● 2009年sun公司被==Oracle(甲骨文)==公司收购。

● Java主要用来做企业级应用开发

● Java应用的六大行业:
桌面应用开发:如IDEA
服务器系统:应用后台
企业级应用开发:微服务,大型互联网应用如:京东首页、后台管理系统、OA办公系统
大数据开发:Hadoop
移动应用开发:Android,医疗设备
游戏开发:如Minecraft

2.Java技术体系

三大技术体系:

  1. JavaSE(标准版):Java技术的核心和基础(标准版本)
  2. JavaEE(企业版):企业级应用开发解决方案(企业级应用版本)
  3. JavaME(小型版):针对移动设备应用的解决方案(做Android)

二、Java入门(重要)

1.JDK简介

JDK(Java Development Kit:Java开发者工具包),必须安装JDK才能使用Java语言
1996年 JDK1.0
2000年 JDK1.3
2004年 JDK5.0
2014年 JDK8.0(LTS)
2018年9月 JDK11.0(LTS)
2021年9月14日 JDK17.0(LTS) LTS(long-term support):长期支持版

2.验证JDK安装是否成功

验证JDK安装是否成功:
win+R,输入cmd,输入命令java -version,如果能看到版本号,则安装成功
验证JDK安装成功

DOS命令窗口出现,‘java’不是内部或外部命令,说明JDK配置有问题,需要重新配置。

3.卸载JDK

卸载JDK:
1.直接删除JDK包
2.删除环境变量(JAVA_HOME和Path)

4.常用命令(javac和java)

● Java程序是高级语言,计算机底层硬件不能识别

5.Java入门程序

5.1Java开发三步骤

编写代码、编译代码、运行代码
文件名全英文,首字母大写,源代码文件的后缀必须是.java
程序员写的代码称为源代码,机器不识别,需要编译(javac)
在这里插入图片描述

5.2HelloWorld程序介绍

在这里插入图片描述

6.IDEA介绍(重要)

6.1IDE概念

IDE(Integrated Development Environment)集成开发环境
● 把代码编写、编译、执行等功能综合起来的开发工具,可进行代码智能提示错误提醒项目管理等等。

6.2IDEA优点

Intellij IDEA简称IDEA,在代码错误提醒,智能代码补全等多方面表现优秀。
1.自动保存
2.自动编译
3.在main方法的左侧小箭头上点击选择Run命令

6.3IDEA管理Java程序的结构

IDEA的层次目录结构,用IDEA开发,最终的目的还是类。

在这里插入图片描述
以上三个目录结构都是为了把类划分的更详细,便于管理项目代码。

整个IDEA组织起来有四层:

  1. project(项目、工程)

  2. module(模块)

  3. package(包)

  4. class(类)——>.java文件

整个基础阶段是一个project,
每天课程是一个module。

6.4用IDEA开发Java程序步骤
  1. 创建工程new Project(空工程)
    最外层项目就是一个文件夹,新建时选Empty Project
    在这里插入图片描述
  2. 设置JDK
    在这里插入图片描述
  3. 创建模块 new Module
  4. 创建包 new Package
  5. 创建类
  6. 编写代码并运行

总结:
在这里插入图片描述

6.5IDEA中设置主题、字体、背景色

主题、字体设置:
在这里插入图片描述
背景色设置:
在这里插入图片描述

6.6IDEA常用快捷键

在这里插入图片描述

三、Java基础语法 (重要)

1.注释

注释对代码进行解释说明,不影响代码执行
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
源代码要变成机器能认识的代码要经过编译,编译过程会将注释抹去。
在这里插入图片描述
在这里插入图片描述
总结:

在这里插入图片描述

2.字面量(常量)

● 数据在程序中的书写格式:
种类:整数 小数 字符 字符串 布尔值 空值
整数字面量:77 88 0 -1
小数字面量:0.1 3.14
字符字面量:单引号引起来的一个字符'A' 'a' ' '
字符串字面量:双引号引起来的任意数量字符"A" "ABC" "" " "
布尔值字面量:true false
空字面量:null
在这里插入图片描述
总结:
在这里插入图片描述

3.变量

3.1变量的定义

● 变量用来记住程序中要处理的数据
格式:

数据类型 变量名 =(字面量);
快递包装盒大小 快递名 = 快递内容;

在这里插入图片描述
age:快递盒名字
int:快递盒大小
18:快递盒里放的东西

在这里插入图片描述
在这里插入图片描述

3.2用变量的好处

用变量记要处理的数据,代码更灵活,管理更方便。

3.3变量的特点

变量中装的数据可变。

在同一个作用域中,不能同时定义两个同名的变量。
但是可以先定义,然后改动值。

3.4变量的应用场景

写程序对数据进行处理很方便
总结:
在这里插入图片描述

3.5使用变量的注意事项

● 变量要先声明后使用
变量是啥类型,就要装什么类型数据
在这里插入图片描述
●变量的作用域
变量有作用域:从定义开始,到最近的一个}结束;
在同一个作用域中,变量的名称不能相同

在这里插入图片描述
定义变量的时候可以不赋初始值;
但在使用时,变量里必须有值

在这里插入图片描述
总结:
在这里插入图片描述

4.关键字、标识符

4.1关键字

Java自己用的一些有特殊作用的词称为关键字,如:public、class、int、double…
在这里插入图片描述
除了48个关键字,还有2个保留字(预留关键字)const、goto,3个特殊直接量(特殊关键字)true、false、null

4.2标识符

标识符是自定义的名字,如类型、变量名等等

4.3标识符的要求

1.基本组成:只能由数字字母下划线(_)美元符($) 等组成。
2.强制要求:不能用关键字(53个)作为名字不能以数字开头区分大小写
在这里插入图片描述
中国被认为是字母,可以用来命名
中文也叫字母,中文也能作类名,也能作变量名。
在这里插入图片描述

4.4标识符命名规范

大小驼峰模式只和第一个字母有关
● 变量名称:小驼峰模式要求首字母小写,如:studyNumber
● 类名称:大驼峰模式要求首字母大写,如:HelloWorld,Student
总结:
在这里插入图片描述

四、Java理论补充(理解)

1.JDK的组成

● JVM:Java虚拟机,真正运行Java程序的地方。程序员写的程序最终被Java虚拟机运行。
● 核心类库:高斯林写的一些Java基础提供好的一些类,可以直接调用,如sout。
Java自己写好的程序,给程序员自己的程序调用。
这是Java的一个便利点,这个思想叫做面向对象编程,拿来直接用。
JVM+核心类库=JRE
● JRE:Java的运行环境
如果不是一个Java开发人员,只是想用Java跑程序,只需要JRE就能保证程序运行。
● 开发工具:java、javac...
在这里插入图片描述
总结:
在这里插入图片描述

2.Java跨平台原理

2.1跨平台定义

Java的特点:一次编译,到处运行

跨平台原理:为不同的平台提供不同的虚拟机,虚拟机具备把.class文件翻译成对应平台能看懂文件的能力。
在这里插入图片描述
Linux(做服务器的)
总结:
在这里插入图片描述

3.JDK安装后配置Path和JAVA_HOME环境变量的原因

3.1Path环境变量

● Path环境变量用来记住程序路径,方便在命令行窗口的任意目录启动程序。
● 在dos中输入命令时,它会按照下面顺序寻找命令文件:

1.dos中当前位置(当前执行的目录下)
2.环境变量中path指定的路径

在这里插入图片描述
在这里插入图片描述

3.2为java、javac配置Path路径

之所以要把java的路径配置到环境变量中,主要是为了方便。

如果不配置环境变量,只能在JDK的bin目录下运行java命令。

一旦配置到环境变量,就可以在电脑的任何位置运行java命令,因为会自动找环境变量里的东西。

在这里插入图片描述
在这里插入图片描述
总结:
在这里插入图片描述
在这里插入图片描述

五、总结

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

day02之Java基础语法

一、数据存储(了解)

1.二进制

● 计算机中所有数据都以二进制形式存储,二进制即只有0和1。
● 也即计算机只认识0和1两个数字。
● 把数字、文字、图片、视频保存到计算机中,要想办法把它们转换为0和1。

2.数字存储

2.1二进制介绍

● 二进制即只有0和1,按照逢2进1的方式表示数字。
在这里插入图片描述

2.2十进制转二进制

在这里插入图片描述
在这里插入图片描述

BIN(binary system):二进制
OCT(octonary number system):八进制
DEC(decimalism):十进制
HEX(hexadecimal):十六进制:A-F表示10-15

2.3计算机中的数据的基本单元和最小单位

最高位认为是符号位,符号位是0表示是正数,符号位是1表示是负数。
在这里插入图片描述
字节是最小单位(数据存储的基本单元),等于8个二进制位,不可拆。

数据存储基本单元:使用8个二进制位为一组,称为一个字节(byte,简称B)

数据存储最小单位:数据基本单元中,每个二进制位称为比特(bit,简称b)1B = 8b

3.总结:

在这里插入图片描述

3.其他存储

3.1字符在计算机中存储

● 转换成对应的ASCII码,把对应的ASCII码转成二进制保存到计算机里。
ASCII编码:即美国信息交换标准编码,规定了字母、数字和其他西欧字符对应的数字编号。
在这里插入图片描述

'0'48
'A'65
'a'97
3.2图片数据在计算机中存储

● 图片由无数个像素点组成。

● 每个像素点的数据:用0~255255255(三原色RGB)表示其颜色。

在这里插入图片描述
在这里插入图片描述

3.3声音数据在计算机中存储

把声音的音波频率转换为对应的数字,再把数字转换为二进制保存到计算机中。
在这里插入图片描述

3.4总结

在这里插入图片描述

二、数据类型(重点)

● 数据类型规定了变量只能存储什么类型的数据

1.分类

数据类型 变量名称 = 初始值;
基本数据类型:4类8种

整型:
byte(1字节)
short(短整型)(2字节)
int(默认)(4字节)
long(8字节)

浮点型:
float(单精度浮点类型)(4字节)
double(双精度浮点类型)(默认)(8字节)

字符型
char(2字节)

布尔型:
boolean(1字节)

在这里插入图片描述
在这里插入图片描述
引用数据剧类型:String
在这里插入图片描述

● 类型转换指的是不同类型的变量相互转换

2.自动类型转换

2.1自动类型转换的概念

类型范围小的变量,可以直接赋值类型范围大的变量。

自动类型转换不会造成数据的损失

帮助理解:变量里面存的是数据,变量是内存中的一块区域,类似于一个快递盒子。

翻译过来就是,小快递盒子里的快递可以直接装进大快递盒子。

再比方说,一杯水可以直接倒入一个大桶,这杯水不会有损失。

在这里插入图片描述
浮点型和整型,在计算机中存储数据时机制是不一样的,不能单纯地比较占几个字节。
在这里插入图片描述

=是赋值运算

在这里插入图片描述

2.2表达式的自动类型转换

● 在表达式中,小类型的变量,会自动转换成表达式中较大范围类型的变量,再参与运算。

● 表达式的最终结果类型由表达式中的最高类型决定

● 表达式中,byteshortchar直接转换成int类型参与运算。

● char单独打印打印的是本身,一旦参与运算,用的是在ASCII表中的值。

在这里插入图片描述
在这里插入图片描述

3.强制类型转换

大范围类型的变量——>小范围类型的变量,这个操作,IDEA认为是有危险的,默认不允许,直接报错,硬干需要强制类型转换。

可以用一桶水倒到一个杯子里来理解

强转:把一个范围类型,强行转换为范围类型
在这里插入图片描述
这种情况下没有问题
在这里插入图片描述
这种情况下发生了数据损失
在这里插入图片描述
注意:

● 强转可能造成数据(丢失)溢出

● 浮点型强转成整型,直接丢掉小数部分,保留整数部分并返回
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、运算符(重点)

● 运算符是对变量、字面量(常量)进行运算的符号。

1.算术运算符

1.1算术运算符介绍

在这里插入图片描述
在这里插入图片描述

1.2+号运算规则

● "+"符号与字符串运算时用作连接符,其结果依然是字符串。

● +号两边只要有一边是字符串,+就当做连接符来用。

+号,能算则算,不能算就拼接在一起。

在这里插入图片描述
在这里插入图片描述

1.3数值拆分

在这里插入图片描述

2.自增自减运算符

在这里插入图片描述

● ++、–只能操作变量,不能操作字面量

● 如果变量单独使用,符号在前、在后没有区别

2.1自增自减的使用注意事项

● ++、–若不是单独使用(若在表达式中同时有其他操作),放在变量前后有明显区别。

赋值运算也是一种运算:
在这里插入图片描述
口诀:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.赋值运算符

3.1基本赋值运算符

就是“ = ”,从右往左看

int a = 10;
//先看“=”右边,把数据10赋值给左边的变量a存储
3.2扩展赋值运算符
符号	用法	作用		底层代码形式
+=		a+=b	加后赋值	a = (a的类型) (a + b);
-=		a-=b	减后赋值	a = (a的类型) (a - b);
*=		a*=b	乘后赋值	a = (a的类型) (a * b);
/=		a/=b	除后赋值	a = (a的类型) (a / b);
%=		a%=b	取余后赋值	a = (a的类型) (a % b);

扩展的赋值运算符隐含了强制类型转换

在这里插入图片描述

4.逻辑运算符

4.1关系运算符

关系/比较运算符,关系运算符用于变量之间的比较。

关系表达式 是包含关系运算符的表达式,它的值是boolean类型

符号	例子		作用							结果
  >		a>b		判断a是否大于b			成立返回true,不成立返回false
  >=	a>=b	判断a是否大于或者等于b	成立返回true,不成立返回false
  <		a<b		判断a是否小于b			成立返回true,不成立返回false
  <=	a<=b	判断a是否小于或者等于b	成立返回true,不成立返回false
  ==	a==b	判断a是否等于b			成立返回true,不成立返回false
  !=	a!=b	判断a是否不等于b			成立返回true,不成立返回false

关系运算符判断数据是否满足条件,最终会返回一个判断的结果,此结果是布尔类型的值:true或者false

4.2逻辑运算符

把多个条件放在一起运算,最终返回布尔类型的值:true、false。

符号	 叫法		 例子		运算逻辑
  &		逻辑与		2>1&3>2		多个条件必须都是true,结果才是true;有一个是false,结果就是false
  |		逻辑或		2>1|3<5		多个条件中只要有一个是true,结果就是true
  !		逻辑非		!(2>1)		取反:你真我假,你假我真!true==false!false==true
  ^		逻辑异或 	2>1^3>1		前后条件的结果相同返回false;前后条件结果不同才返回true


  &&	短路与		2>10&&3>2	判断结果与“&”一样,过程不同:左边为false,右边则不执行
  ||	短路或		2>1||3<5	判断结果与“|”一样,过程不同:左边为true,右边不执行

注意:
在java中,“&”、“|”:无论左边是false还是true,右边都要执行。

&&、||运算效率更高,在开发中使用的更多。
在这里插入图片描述

5.三元运算符

格式:条件表达式?值1:值2;

执行流程:首先计算关系表达式的值,若为true,返回值1,若为false,返回值2。

6.运算符的优先级

在这里插入图片描述

四、键盘录入(重点)

在这里插入图片描述
核心类库就是API:应用程序编程接口

Java写好的程序,程序员可以直接调用。

Java为自己写好的程序提供了相应的程序使用说明书(即API文档)。

在这里插入图片描述
Scanner是JDK提供好的一个类,需要可以直接调用。
在这里插入图片描述
在这里插入图片描述

day03之程序流程控制

控制程序的执行顺序

程序的三种控制结构:
顺序结构:自上而下地执行代码
分支结构:根据条件选择对应代码执行
循环结构:控制某段代码重复执行

一、分支结构

1.if分支

1.1if语句介绍

● 根据条件(真或假)决定执行某段代码

if第一种形式
在这里插入图片描述
if第二种形式

在这里插入图片描述

if第三种形式

在这里插入图片描述
在这里插入图片描述

1.2if使用的几个常见问题

● 如果if语句的{}中只有一行代码,()可以忽略不写(但不推荐忽略)。

● if(条件){},()后不能跟“;”,否则{}中的代码将不受if的控制。

1.3练习:用户登录

在这里插入图片描述
在这里插入图片描述

2.switch分支

● switch分支通过比较值决定执行哪条分支

switch分支执行流程:

1.先执行表达式的值,用待匹配的值去匹配对应的case。

2.与哪个case的值匹配为true就执行对应的语句体,遇到break就结束switch分支。

3.所有case都匹配不到,执行default块中的语句体。

在这里插入图片描述
在这里插入图片描述

3.switch使用时的注意事项

1.switch分支语句()中的表达式类型只能是byteshortintchar,JDK5开始支持枚举,JDK7开始支持String
不支持doublefloatlong
2.case给出的值不能重复,并且只能是常量不能是变量
3.使用switch时忘写break会出现穿透现象
穿透现象
当匹配成功一个case以后,执行完语句体之后,没有break。
就会忽略后面的条件判断直接执行语句体,直到再次出现break或者整个switch语句结束。
穿透现象可以加以利用,优化代码。

在这里插入图片描述

4.if和switch比较

if适合做区间匹配功能更强
switch适合做值匹配性能更好

二、循环结构

● 控制一段代码重复执行多次。

1.for循环

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2.for循环案列

求1-5之间 的数据和
在这里插入图片描述
在这里插入图片描述
求1-10之间的奇数和
在这里插入图片描述
在这里插入图片描述
水仙花数
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

3.while循环

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

4.while循环案例

折纸案例

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
for和while循环都可以实现循环,使用时如何选择?

for:明确知道循环次数

while:不知道循环多少次

5.do-while循环

do-while循环的特点是:先执行后判断。

在这里插入图片描述
在这里插入图片描述


初始化语句;
do{
	循环体语句;
	条件变更语句;
}while(条件判断语句);

6.三种循环的对比

在这里插入图片描述

7.死循环

7.1死循环的概念

死循环:
是指可以一直执行下去(即保证循环的条件判断语句永远成立)的循环,若没有干预不会停下来。

7.2死循环的写法

在这里插入图片描述

8.循环嵌套

8.1概念

即循环中又包含循环。

8.2特点

外部循环每循环一次,内部循环会全部执行完一轮。

外层循环执行一次,内层循环执行一轮。

8.3案例:连续说3天,每天说5遍“我爱你”

在这里插入图片描述

8.4案例:在控制台打印4行5列的矩形

在这里插入图片描述

三、跳转关键字:break、continue

1.介绍

break:跳出并结束当前所在循环的执行(break只能用于结束所在循环 或 结束所在switch分支的执行)

(帮助理解:吃包子,吃出蟑螂,本包子不吃了,别的包子也都不吃)

continue:跳出当前循环的本次执行,直接进入循环的下一次执行(continue只能在循环中使用)

(帮助理解:吃包子,一个掉到地上,本包子不吃了,拿下一个包子来吃)

2.案例:密码验证

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

四、Random类:生成随机数

1.Random类的作用、使用及注意事项

举例:随机点名、年会抽奖

Random 作用:生成随机数

在这里插入图片描述
在这里插入图片描述

2.总结:

在这里插入图片描述

3.案例:猜数字游戏

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

day04 习题课

day05之Java数组

一、数组介绍

数组是一个容器,用来存储一批同类型的数据

有变量,为何用数组?
答:遇到批量操作同类型数据时,数组变量更合适。
在这里插入图片描述
在这里插入图片描述

二、数组定义和访问

1.静态初始化数组

● 定义数组的时候直接给数组赋值(要求在定义数组时已知要存的元素)
在这里插入图片描述

注意:
数据类型[ ] 数组名也可写成数据类型 数组名[ ]
● 什么类型的数组只能存放什么类型的数据

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

注意:
数组变量名中存储的是数组在内存中的地址,数组是一种引用类型数据。

● **基本数据类型:**四类八种,变量记录的就是数据本身

● **引用数据类型:**变量记录的是内存地址,该变量对应的类型是引用数据类型

判定一个数据是否是引用类型,只需要判定这个变量里面存的是内存地址还是数据本身

在这里插入图片描述

2.数组的访问

数组名[索引]

在这里插入图片描述

如上图,通过变量arr找内存地址,通过内存地址再找索引0,通过索引就能找到数据。
在这里插入图片描述

ArrayIndexOutofBoundException

数组索引越界异常

在这里插入图片描述

3.数组的遍历

**遍历:**一个一个地访问数据

ages.length:ages数组的数组长度

在这里插入图片描述

数组遍历求和:累加思想,定义一个sum变量

在这里插入图片描述

4.动态初始化数组

静态初始化数组:创建数组时已知里面的元素

动态初始化数组:创建数组时不知道里面的元素

● 定义数组时先不存入具体元素值,只确定数组存储的数据类型数组长度

数组的动态初始化格式:

数据类型[] 数组名 = new 数据类型[长度];
int[] arr = new int[3];

在这里插入图片描述
在这里插入图片描述

三、数组常见案例

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
声明变量快捷方式:列选择
Alt+按住鼠标左键,光标下拉

在这里插入图片描述
数据交换要引入一个临时变量temp
临时变量思想
在这里插入图片描述
数组反转要引入双指针思想,定义两个指针变量,分别指向数组的首尾索引
在这里插入图片描述

在这里插入图片描述

随机排名/打乱数组
在这里插入图片描述

在这里插入图片描述

四、数组执行原理

1.数组的执行原理

计算机最后拿到的是一个class文件,由JVM来执行,JVM是代码真正运行的地方。class文件中的main方法会被JVM自动调用。
在这里插入图片描述

堆内存中存放new出来的,
随机数对象,键盘对象,数组,对象会存在堆内存中。

在这里插入图片描述

Java内存分配:

● 方法区:存放字节码文件
● 栈(内存):存放方法和变量
● 堆(内存):new出来的东西(对象)

● 本地方法栈
● 寄存器

基本类型是固定的四类八种,除了基本类型都是引用类型。

基本数据类型的变量和值都存在栈中。

引用数据类型的变量,变量名存在栈中,变量名下存的是一个地址,这个地址对应的真正位置在堆里面。

在这里插入图片描述

在这里插入图片描述

2.多个变量指向同一个数组的问题

帮助理解:arr1和arr2变量想成家门的钥匙,我和我媳妇都有家门的钥匙,钥匙对应的内存地址中存的数据想成家里的家具,我把其中的值修改,比如把家里的床卖了,媳妇的视角里也会受到影响。

在这里插入图片描述
在这里插入图片描述

五、Debug工具的使用

Debug工具:

IDEA自带的断点调试工具,可以控制代码从断点开始一行一行地执行,然后详细观看程序执行的情况。

Debug工具基本使用步骤

1.在需要控制的代码行左侧,点击一下形成断点

2.选择Debug方式启动程序,启动后程序会在断点暂停

3.控制代码一行一行往下执行

在这里插入图片描述

注意事项:

1.打断点
(希望程序在哪一行暂停),断点要打在正式的代码行,不要打在类名方法名导包空行等位置。

2.使用debug运行程序

3.控制程序一步一步执行
Step Into:下一步如果有方法就会进入方法
Step Over:下一步如果有方法,方法会自动执行完成(不会进入方法)

4.查看程序执行的情况
Debugger:查看方法执行情况,查看程序中变量的变化情况
Console:普通控制台,输入数据或者查看输出的数据

5.停止debug:取消断点如果不取消断点,下次运行时又会暂停到断点处。

6.调试时,灰色的提示指的是每一行变量的值

在这里插入图片描述

扩展:

如果程序很多,不知道打了哪些断点,可以点击View Breakpoints,在这里可以看到所有的断点。
在这里插入图片描述
在这里插入图片描述

而点击Mute Breakpoints之后,所有的断点都将不再生效。

在这里插入图片描述

六、数组总结

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
当把一个引用类型变量置为空时,相当于断开了和堆内存的联系,当联系断开之后,不能再通过此变量访问堆内存中对应的空间里的任何东西,包括长度和内容。如果强行访问会出现空指针异常。
在这里插入图片描述
在这里插入图片描述

观察变量值的方法:
可以看Debugger中Variables中的值,也可以直接看程序中的值。
在这里插入图片描述

day6之Java方法

课程设计:
1.先介绍
2.讲语法
3.做案例练习
4.讲理论

一、方法介绍

方法是把一些代码打包起来,在需要的地方可重复使用。

1.1什么是方法

1.方法是把一些代码打包在一起,用到的时候就调用。

2.方法是程序中最小的执行单元。程序员写的代码如果想执行,必须放在方法里面,Java在运行代码时是以方法为单元的,至少要运行一个方法,不能没有方法去直接运行一行代码。

3.方法只有在被调用时才会执行。

main方法是提供好的,main方法由JVM自动调用。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.2用方法的好处

1.提高代码的复用性(抽取重复代码,重复使用)

2.提高代码的可维护性(方便修改)
在这里插入图片描述

二、方法定义和调用

方法定义是把一些代码打包在一起,用到的时候就调用

方法定义
把一些代码打包在一起,该过程称为方法定义

方法调用
方法定义后不直接运行,需要手动使用才能执行,该过程称为方法调用

1.基本方法

1.1基本方法的定义和调用的格式和范例

在这里插入图片描述

1.JVM执行程序的入口是main方法,main方法和别的自定义的方法是并列(平级)关系,方法不能嵌套定义。

1.2IDEA中设置方法分割线

FIle->Settings->Editor->General->Appearance->选中Show method separators

2.方法从上往下顺序执行的过程中,遇到方法就会跳到方法里面执行,执行完毕之后再回到执行点。
(帮助理解:高速公路服务区)
在这里插入图片描述

3.调换方法定义顺序不会影响到程序的执行结果。

4.调换方法调用顺序会影响程序的执行结果。

5.如果在eat()方法中调用drink(),在drink()方法中调用eat(),方法会循环调用,造成堆栈溢出。

StackOverflowError:堆栈溢出异常
在这里插入图片描述

1.3基本方法定义总结:

在这里插入图片描述

2.带参数的方法

2.1带参数方法的定义和调用

在这里插入图片描述
注意:

方法调用时。实参必须与形参保持相同的类型数量顺序

形参:全称形式参数,方法定义中的参数。

实参:全称实际参数,方法调用中的参数。

在这里插入图片描述

形参列表即参数列表

在这里插入图片描述

3.带返回值的方法

方法的返回值就是方法运行的最终结果
当调用一个方法时,如果方法的执行结果会在后续程序中用到,就需要方法将运行的结果返回。

3.1带返回值方法的定义

在这里插入图片描述

3.2带返回值方法的调用

在这里插入图片描述

return部分返回数据的类型必须和方法定义时声明的返回值类型一致

在这里插入图片描述
总结:
在这里插入图片描述

4.方法总结

方法的注意事项:
main方法虽然我们没有调用,但是JVM调用了。

在这里插入图片描述
在这里插入图片描述
在return语句下面写的代码是无效代码,永远执行不到。
在这里插入图片描述
返回值类型是void,不能再接收结果
在这里插入图片描述

三、方法案例

1.方法的编写步骤

1.根据需求,判断方法是否有参数。参数的数量和类型分别是什么。
即通过分析确定参数列表

2.分析方法是否有返回结果。返回值的类型是什么。
即通过分析确定返回值类型

3.方法要处理的业务(具体实现)
在这里插入图片描述

2.计算1-n的和

在这里插入图片描述

在这里插入图片描述

3.判断一个整数是奇数还是偶数

分析参数的方法:把自己当成这个功能,缺什么要什么。

在这里插入图片描述

在这里插入图片描述

4.打印int类型的数组内容

在这里插入图片描述

在这里插入图片描述

数组转换成字符串
在这里插入图片描述

在这里插入图片描述

Arrays.toString(数组名);
Java已经提供了把一个数组转成字符串的方法

5.比较两个int类型的数组是否一样

在这里插入图片描述
在这里插入图片描述

四、方法重载

1.方法重载定义

重载是方法与方法之间的关系。

在同一个类中,名称相同形参列表不同的多个方法,这些方法构成重载关系。
在这里插入图片描述

2.方法重载意义和场景

Java支持方法重载,是为了让调用者不用记忆太多繁琐的方法名称(方便)

开发中为了经常处理一类业务,提供多种解决方案,可以使用重载来设计程序。

如:System.out.println();在底层通过方法重载
在这里插入图片描述

3.方法重载案例

在这里插入图片描述

在这里插入图片描述

五、方法执行原理

1.执行原理

方法被调用的时候,才会进入栈内存中运行。

栈是一种先进后出的数据结构。

在这里插入图片描述
在这里插入图片描述
sum方法运行结束后弹栈
在这里插入图片描述
main方法运行结束后弹栈
在这里插入图片描述

在这里插入图片描述
方法调用的时候入栈,只要调用完毕,就会弹栈

需要注意的是
在一个方法内部定义的变量,它在内存中的位置就在这个方法的内部。

不能试图从main方法中强行拿c变量,main方法和sum方法是隔离的,拿不到c变量,sum方法可以把值传递过来,但main方法不能直接使用c变量。

(帮助理解:邻居孩子可以抱抱,但不能直接成自己的。)

在这里插入图片描述
在这里插入图片描述
方法调用的时候入栈,只要调用完毕,就会弹栈

2.参数传递

2.1参数传递概念

Java的参数传递机制都是:值传递

参数传递:调用方法的时候,把实参传给形参的过程

所谓值传递,指的是在传输实参给方法的形参的时候,传输的是实参变量中存储的值的副本

实参:全称实际参数,指方法调用中的参数

形参:全称形式参数,指方法定义中的参数,作用是接收实参中的数据
在这里插入图片描述
在这里插入图片描述
main方法中的a和change方法中的a没有关系,一个在main方法区域中,一个在change方法区域中,这两个方法中的变量相互之间是隔离的,没有任何关系。

change方法中a=20;在改变a的值,改变的是change方法里a的值,change方法执行完毕之后弹栈。

main方法中的a没有发生变化。

2.2基本类型的参数传递:传递的是变量中保存的值

对于基本类型(4类8种),它们在参数传递的时候,传递的都是变量中存进去的值。

在另一个方法中改动这个值,不会影响本身这个方法。

因为传过去的是副本,改动的是复制的内容,对本身没有影响。

在这里插入图片描述

2.3引用类型的参数传递:传递的是变量中保存的地址

由于是把地址传递过去了,因此两个地方访问的是同一块空间(即同一块堆内存)。

基本数据类型变量里面保存的是值本身

引用数据类型变量里面保存的是内存地址

在这里插入图片描述
在这里插入图片描述
堆中存储的是数据真正的内容
栈中只会存储一个内存地址值
在这里插入图片描述

不管是基本数据类型还是引用数据类型,参数传递赋值时,赋过去的都是变量中保存的值的副本。

变量中原本保存的是地址值,就把这个地址值复制一份传递给change方法的形参。

由于引用类型变量存的是地址值,change方法中的arrs中的值和main方法中的arrs中的值指向的是同一块内存空间,通过在change方法中修改内存空间中所存的值,通过main方法中的arrs能看到修改后的结果。
在这里插入图片描述
在这里插入图片描述

2.4总结

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

参数传递,不管是基本类型还是引用类型都是值传递,传递的都是变量中保存的值。
此处,main方法和change方法中的a是完全隔离的,在change方法中修改a的值,main方法中a不会受任何影响。
(下图的帮助理解:同桌和你借电子书,你把电子书直接传给同桌,同桌把电子书改了、扔了、撕了,和你的电子书没有关系,你的那本还是那本。)

在这里插入图片描述

change方法中的arrs变量和main方法中的arrs变量,这两个变量指向了堆内存中的同一个内存区域。
(下图的帮助理解:你把电子书存到一个秘密的盘中,你给同桌的是一个盘的访问密码,你俩访问的是同一个东西,同桌现在把电子书修改、销毁,你也会受影响。)

在这里插入图片描述

day07-09之编程训练&比赛

20个题目

day10之面向对象

詹姆斯·高斯林:万物皆对象

一、面向对象

1.基础认知

1.1基本概念

类是创建对象的模板,要创建一个对象必须先有类。

类中主要包含两部分内容:属性(变量 静态)和动作(方法 动态)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

直接写在类里面而不在方法里面的变量称为成员变量,也叫全局变量。

写在方法里面的变量:局部变量

类是创建对象的模板,要创建一个对象必须要先有类。

类是一个模板,想要用类必须创建它的对象。

类中主要包含两部分内容:
属性:变量(静态)
动作:方法(动态)

在这里插入图片描述

面向对象编程基本步骤:

1.创建一个类(编写属性和动作)

2.编写测试类(main方法,创建对象,属性赋值,调用方法)

在这里插入图片描述

1.2一个类可以创建个对象

由同一类创建出来的两个对象没有关系,(如:两个同学买的同一个品牌同一个型号的电脑,其实都是同一个模板制造出来的,两个电脑本身一模一样,但是没有任何关系)

2.深入理解

2.1面向对象编程的好处?

万物皆对象。

汽车的数据找汽车对象处理

手机的数据找手机对象处理

学生的数据找学生对象处理

即谁的事情谁来做,谁的数据谁负责。

好处:更符合人类思维习惯,编程更简单、更直观。

2.2程序中的对象到底是什么?

对象是一个具体的东西,可以用属性行为对其进行具体描述。

在这里插入图片描述

如果要创建一个汽车对象,必须要先有类

在这里插入图片描述

汽车的属性,都是在类中定义好的,对象只是把这些属性做了一个具体化,具体出来才是宝马,5系,黑色,50w。

在这里插入图片描述

类是抽象的,对象是对类的一个具体描述。

因此,可以总结如下:

对象是由类创建出来的,类是创建对象的模板,对象是类的具体实现

在这里插入图片描述
帮助理解:

类是抽象的,可以理解成月饼模具
做出来的一个个月饼是具体的对象。

模板是什么样,对象就得是什么样。
模板是抽象的,对象是具体能产生的东西。

这就是对象和模板(类)之间的关系。

2.2.1总结

属性具体来说就是变量
行为具体来说就是方法

类是对象的抽象
对象是类的具体

在这里插入图片描述

2.3对象是怎么出来的?

对象是由类创建出来的,类是创建对象的模板,对象是类的具体实现

2.4创建对象注意事项

一个代码文件中,可以写多个class类,但只能一个用public修饰,并且,public修饰的类名必须与代码文件名一致。

如下图这种情况中,只能Teacher类用public修饰。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

3.案例

在这里插入图片描述
在这里插入图片描述

4.内存图

对象在计算机中的执行原理

在方法中声明的变量出现在栈内存中,
在类中声明的变量出现在堆内存中。

也就是说变量存储的位置跟着它的“老大”走

1.方法在栈里面,方法里声明的变量就在栈里面。

2.类实例化出来的对象最后在堆里面,因此对象里面的直接属性就会进入堆里面。

在这里插入图片描述

类的地址:标识对象是由哪个类创建出来的。

方法不进入堆内存,方法的字节码永远存在于方法区中。当方法被调用的瞬间,方法会压栈。

在这里插入图片描述

如上图,如果某个对象没有任何对象指向它,需要注意:

当堆内存中的对象,没有被任何变量引用(指向)时,就会被判定为内存中的==“垃圾”==。

Java存在垃圾自动回收机制,会自动清除掉垃圾对象,程序员不必操心。

总结:

在这里插入图片描述

二、封装

面向对象三大特征:封装、继承、多态

1.封装理论

1.1什么是封装?

在面向对象程序设计中,应把对象的属性和行为设计到对象内部去,且对象中的数据不能被随意访问。

1.2为什么要封装?

在类中默认定义的变量随时可被其他类访问、修改,是不安全的。
在这里插入图片描述

1.3封装的设计规范

合理隐藏、合理暴露

一个变量一旦被private修饰,它就不能被其它的类随意修改。

本类可以修改,只是其他的类不能随意修改

(帮助理解:你自己的娃想打就打,别人要打肯定不行)

在这里插入图片描述
成员变量用private修饰之后,提供公用(public)的set方法,之后想修改此成员变量的值,可以调用公共的方法。

(帮助理解:我把我家娃藏起来,别人想打打不着,但是可以让我来打,调用我的打娃方法)
在这里插入图片描述

隐藏属性,暴露方法!

在这里插入图片描述
总结:
在这里插入图片描述

2.this关键字

2.1Java就近原则

在这里插入图片描述
“ this ” : 当前对象(成员变量位置)
“ . ” : 的
在这里插入图片描述

2.2this是什么

this是一个变量,用在方法中,代表当前方法所属的对象

直接打印 this
在这里插入图片描述

2.3this的应用场景

this主要用来解决变量名称冲突问题

在这里插入图片描述

2.4成员变量和局部变量的区别

在这里插入图片描述

2.5this的执行原理

在这里插入图片描述
总结:

在这里插入图片描述

3.构造器

3.1构造器的特点

构造器又叫构造方法,用于创建对象,
有以下几个特点:

1.方法名必须和类名保持一致

2.方法没有返回值,也不能用void修饰

3.创建对象时,构造方法会被自动调用

4.一个类中若没有任何构造方法,Java会自动生成一个无参构造

在这里插入图片描述

构造器的作用:

可以在创建对象时执行一些有意义的代码

3.2构造器的应用场景

创建对象时同时完成对 对象成员变量(属性) 的初始化赋值

格式:Student s = new Student("张三",12);

在这里插入图片描述

3.3构造器注意事项

一个类中,若没有任何构造方法,Java会自动生成一个无参构造。

一个类中,一旦有了有参构造方法,Java将不会再生成无参构造,此时若需要无参构造,可自行创建。

3.4总结

在这里插入图片描述

4.案例

4.1对前面内容的总结

面向对象,把一个类的属性和方法封装到内部,属性不能被别人随意访问,需要用private修饰,此时成员变量不能被别的类访问,所以对外提供公共(public)的方法。

提供方法时引出一个问题,在传参时会出现局部变量和成员变量的命名冲突问题,又引入this关键字。

最后在创建完对象赋值时如果值非常多,赋值可能非常麻烦,又引入构造器(也即构造函数),它可以在new一个对象的时候,直接把参数传递进去。

在这里插入图片描述

4.2案例:学生类

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

4.3案例:航班类

在这里插入图片描述
在这里插入图片描述

三、JavaBean

1.介绍

JavaBean,又叫实体类,是一种特殊形式的类。
在这里插入图片描述

实体类的两个要求:

1.类中的成员变量都要私有,对外提供相应的get、set方法。

2.类中必须有一个公共的无参的构造器,也可以提供一些带参构造器,用于属性赋值。

变量可以保存数据,set方法和构造方法都可以存数据,get方法可以取数据。只留下这些就可以满足实体类。

实体类只负责数据的存取,而对数据的处理交给其他类来完成,以实现数据和数据业务处理相分离。

在这里插入图片描述

数据单独在一起,业务单独在一起。

(帮助理解:

比如StudentOperator类是你,Student类是你的钱包类,如果有人(比如我)向你借钱,我就需要找到你这个对象,你的钱在你的钱包里,之后你在你这个类里再去操作钱包,把钱拿出来给我。

就好像把原来的类一分为二,Student类中只保留数据本身以及和本身相关的存取方法,其他和业务相关的方法放到StudentOperator类中。

在StudentOperator类中,要操作Student类,就需要在StudentOperator类中维护一个Student对象的引用(即提供一个Student的变量)。

即你本身要有一个你的钱包的引用,没有这个引用你就找不到你的钱包。)

在StudentOperator类中维护一个student引用时,只声明一个Student类型的变量而不赋值,则这个变量默认值为null,再用这个变量调用方法时,会出现空指针异常。

需要做的是,先赋值(也可以先写死),然后就可以创建对象测试了,此时应该创建的对象是StudentOperator类的对象(因为只要创建了StudentOperator类的对象,一运行private Student student = new Student(1001,"张三",'男',19);这句代码,就把Student对象创建出来了。)

在这里插入图片描述

在这里插入图片描述

此时,我们需要创建一个测试类,在main方法里创建一个studentOperator的对象,然后就可以调用studentOperator的方法且不需要赋值,可以直接调用。
在这里插入图片描述

在这个版本中,student对象的属性是写死在StudentOperator类中的,此时如果要修改student对象属性,就需要在StudentOperator类中进行修改。

这是不合理的,因为Student类和StudentOperator类是提供给别人用的,使用时还需要修改类本身的代码。

所以不能写死,应该在调用时传递什么对象就是什么对象。所以想要修改StudentOperator类中的属性student的值,应该给StudentOperator类中的属性(student变量)提供一个set方法,也可以提供全参构造方法。

只需要调用构造器,new一个对象,把对象传进去即可。(如下图)
在这里插入图片描述
现在如果要把张三改成李四,只需要在测试类中修改即可。

此时可以认为,现在的Student类和StudentOperator类就和JDK提供的random是一样的。不需要修改别人的代码,只需要修改给别人传的参数即可。

总结

1.实体类的作用:

实体类只负责保存数据,实体类中的东西都是和数据相关的。

变量可以保存数据,set方法和构造方法都可以存数据,get方法可以取数据。只留下这些就可以满足实体类。
在这里插入图片描述

2.案例

模仿电影信息系统

在这里插入图片描述

day11之字符串和集合

一、常用API

1.API概念

API:应用程序编程接口

API是别人写好的类,要使用得先学习其中的方法。

API是别人写好的一些程序,程序员直接拿去调用就可以解决问题。

使用API的原因:Java已有20多年发展历史,提高开发效率,不用重复造轮子。

2.包的概念和作用

包的作用:

包是分门别类管理程序的,即把类进行分目录管理,让类看起来没有那么乱。

也就是说,包就是来组织类这个结构的。

如下图是Java提供好的一些包:
在这里插入图片描述

day12之ATM系统

需求分析:


Account	银行账户类(实体类)
	属性:
		cardId: 卡号 8位数字 系统自动生成
		username: 姓名 用户输入
		password: 密码 用户输入,还要重复校验
		gender: 性别 用户输入, 只能是男 女
		money: 余额 初始化为0
		limit: 每次的提现额度 用户输入



ATM(实体操作类)
	启动系统的方法 start: 展示主界面,展示用户可以选择的功能
		用户登录功能login: 登陆成功,展示子界面: 展示用户可以选择的功能
		查询账户功能 showLoginAccount
		存款功能depositMoney
		转账功能 transferMoney
		取款功能 drawMoney
		注销功能 cancelAccount
		修改密码功能 updatePassword
		用户开户功能 createAccount: 开户成功,回退到主界面

	
	
ATMTest(测试类)
	创建ATM,并调用start方法启动   



 

一、项目技术分析

ATM系统技术选型:

Account:实体类

ATM:实体类的操作类

1.面向对象编程:
银行系统中的每个账户都是一个账户对象:需要设计账户类Account用于创建账户对象封装账户信息。

ATM也是一个对象,需要设计ATM类,代表ATM管理系统,负责对账户的处理。

2.使用集合容器:
ATM管理类中需要提供一个容器来存储系统中全部账户对象的信息,可以选择ArrayList集合。

3.流程控制:
做一些判断和循环:需要结合分支、循环、跳转关键字等程序流程控制知识,用来控制系统的业务流程。

4.使用常见API:
登录信息的内容比较,数据的分析、处理都需要常用API解决,如使用String。从键盘录入,需要用到Scanner对象。

二、系统架构搭建、欢迎页设计

1.系统架构搭建

  1. 定义一个账户类Account,需要包含(卡号、姓名、密码、性别、余额、单次提现额度)

  2. 定义一个ATM类,用来代表ATM系统,负责

  3. 定义一个测试类Test,负责对我们开发的ATM系统进行测试。

2.系统欢迎页设计

1.先定义一个账户实体类:

a.Account实体类

属性:

private String cardId;//卡号(8位数字 系统分配)
private String username;//姓名(字符串 用户输入)
private String password;//密码(字符串 用户输入,需要输入两次且一致)
private char gender;//性别(字符 用户输入且只能是男 女)
private double money;//余额(浮点型 开户默认为0)
private double limit;//单次提现限额(浮点型 用户输入)


在这里插入图片描述

2.再定义一个ATM类(实体操作类),负责业务处理,业务处理就是用方法编写功能。

在ATM类中设计一个start()方法,方法负责展示欢迎界面。
欢迎界面用户可以选择的功能有:登录(login)和开户(createAccount)。

b.start()方法


//启动系统的方法start:展示主界面,展示用户可以选择的功能
public void start(){	
	//死循环
	while(true){
		System.out.println("===欢迎进入银行系统===");
		System.out.println("1.用户登录");
		System.out.println("2.用户开户");
		System.out.println("选择您要操作的命令:");

		//创建键盘对象,接收用户输入的指令
		Scanner scanner = new Scanner(System.in);
		//使用String接收的原因是避免程序运行出错
		String command = scanner.next();
		switch(command){
			case"1":
			System.out.println("开始执行用户登录指令");
				break;
			case"2":
			System.out.println("开始执行用户开户指令");
				break;
			default:
				System.out.println("用户输入指令有误,请重新输入");
				break;
		}

	}
}

分析需求,不管是上述的启动方法(start()),还是登录、开户方法,每个方法都要用到Scanner的对象,所以应该把scanner对象提升为成员变量。

因为成员变量可以被类中的所有方法访问,这样就不用在每个方法中单独创建。

3.再定义一个测试类Test,负责对开发的ATM系统进行测试。

在这里插入图片描述

小结:
在这里插入图片描述
对应面向对象编程的思想,Account类就是实体类,ATM类就是操作类,Test类就是测试类。

项目再大都遵循对象思想。

至此,搭建系统架构完成。

三、开户功能实现

欢迎页有两个功能,登录和开户。

我们先开发开户功能,因为开户之后才能登录。

所谓开户,就是新增一个账户,即给系统的账户集合中添加一个账户对象。

在ATM机中应该维护一个账户的集合,和Person的操作类中维护了一个Person的集合是一个道理。
在这里插入图片描述

系统开户的本质就是,从键盘接收用户输入的账户属性,保存在一个账户对象中,再把这个account账户保存到账户集合中。

public class ATM{
	ArrayList<Account> accountList = new ArrayList<>();
}

c.createAccount()方法


//开户方法:本质上是向ATM系统中的账户集合中保存一个新账户(信息来自于用户键盘)
public void createAccount(){
	System.out.println("===系统开户操作===");
	//1.创建账户对象(属性没有值)
	Account account = new Account();//这个account里的各个属性还没有值
	
	//2.对账户对象的各个属性进行赋值(键盘录入)
	//为各个属性一个一个进行赋值
	//2-1 cardId:卡号(8位数字 系统分配)
	String cardId = GenCardId();
	account.setCardId(cardId);

	//2-2 username:姓名(字符串 用户输入)
	System.out.println("请您输入账户用户名");
	String username = scanner.next();
	account.setUsername(username);
	
	//2-3 password:密码(字符串 用户输入,需要输入两次且一致)
	
while(true){


	System.out.println("请您输入账户密码");
	String password = scanner.next();
	System.out.println("请您再次输入密码以确认");
	String password2 = scanner.next();
	if(!password.equals(password2)){
		System.out.println("两次输入的密码不一致,请重新输入");
		

	}else{
		//密码一样,赋值到对象,并且跳出循环
		account.setPassword(password);
		break;//跳出循环
	}


}
	
	//2-4 gender:性别(字符 用户输入且只能是男 女)

while(true){

	System.out.println("请您输入您的性别:");
	char gender = scanner.next().charAt(0);
	if(gender!='男&&gender!='女){
		//用户输入有误
		System.out.println("您输入的性别有误,请重新输入");
	}else{
		//输入正确——>先赋值,再跳出
		account.setGender(gender);
		break;
	}

}
	
	//2-5 money:余额(浮点型 开户默认为0)
	//余额直接给个默认值就行,刚开完户余额一定是0
	
	account.setMoney(0);
	
	//2-6 limit:单次提现限额(浮点型 用户输入)
	
while(true)	{
	
	System.out.println("请您输入账户单次提现限额");
	double limit = scanner.nextDouble();
	if(limit<0){
	System.out.println("您输入的限额额度有误,请重新输入");
	
	}else{
		account.setLimit(limit);
		break;
	}
	
}
	//3.将账户对象保存到账户集合中
	//集合应该new在方法的上面,这个账户集合在ATM类中的很多方法中都要使用,创建账户、查询需要在集合里拿,所以new集合应该放在全局变量的位置
	accountList.add(account);
	
	//4.提示开户成功
	System.out.println("恭喜您,您开户成功,您的卡号是:88888888");
}

注释后面+todo,todo意思就是待办。

当在注释中加入todo后,能在IDEA的TODO:中看到未完成的代码。

生成卡号的方法:

d.genCardId()方法

public class ATM{
	
	Random random = new Random();
}
//注释后面+todo,todo意思就是待办。
//当在注释中加入todo后,能在IDEA的TODO:中看到未完成的代码。
//todo 生成卡号
//八位数字 不能重复
public String genCardId(){

while(true)	{

	//1.生成8位数字的卡号
	//循环8次,每次随机生成一个数字,最后将8次生成的结果拼成一个字符串即可
	//随机生成要用到random对象,new random()可以写在本方法中,但考虑到其他对象也可能使用它,所以卸载全局变量的位置
	String cardId = "";
	for(int i=0; i<8; i++) {
	cardId += random.nextInt(10);//0-9
		}

	//2.保证卡号不重复
	//目前cardId变量中保存的是刚生成的新卡号,要跟accountList集合中所有账户的卡号做对比
	if(findByCardId(cardId)==null) {
		//在集合中找不到说明生成的账号没有被别人使用,可以继续开户
		return cardId;
		}else{
		//虽然没有break跳出while循环,但又return。return也可以结束方法,把结果返回去,跳出循环。
		//别人已经使用了,需要重新生成
		}
		
	}
	
}

此时需要一个新方法,根据cardId查询账户:

e.findByCardId()方法

public Account findByCardId(String cardId){
	//遍历集合得到每个账户
	for(int i=0;i<accountList.size();i++){
		Account account = accountList.get(i);
		//将传入的cardId和集合中获取到的account的cardId对比
		if(cardId.equals(account.getCardId)){
			return cardId;//将对象返回
			}
		}
	
	//循环结束,没有找到cardId对应的对象
	return null;
	}
}

最后将提示开户成功信息中打印的内容修改:

//在Account实体类的getUsername()方法中加一个性别判断
public String getUsername(){
	String u = gender =={ '男' ?  username+"先生" : username+"女士" };
	return u;
}


//4.提示开户成功
System.out.println("恭喜您,您开户成功,您的卡号是:88888888");
}

System.out.println("恭喜您,"+account.getUsername()+"开户成功,您的卡号是:"+account.getCardId());
}


在这里插入图片描述
在这里插入图片描述

四、用户登录功能

1.若系统中没有任何账户对象,不允许登录。

2.让用户输入登录的卡号,先判断卡号是否正确,若不正确要给出提示。

3.若卡号正确,再让用户输入密码。
若密码不正确要给出提示,若密码也正确,给出登录成功的提示。

f.login()方法

//登录方法login():本质是从控制台接收用户输入的账号和密码,与开户时留下的账号和密码进行对比。

public void login(){

	//0.提前声明变量
	Account account = null;


	//1.判断当前ATM系统中是否没有任何账户,若是,直接返回展示
	if(this.accountList.size()==0) {
		System.out.println("您好,当前系统还没有账户");
		
		//结束当前方法
		return;
	}

	//2.接收用户控制台输入的账户信息,使用提供的账户信息去list中查询,若查询不到,重新输入。
while(true){

	System.out.println("请您输入登录卡号:");
	String cardId = scanner.next();
	account = findByCardId(cardId);
	if(account == null) {
		//账户有误
		System.out.println("系统中不存在该账户卡号");
	}else{
		//查到了账户,跳出循环,继续比对密码
		break;
	}

}

	//3.接收用控制台输入的密码信息,使用提供的密码信息和刚才找到的账户中的密码比对,如果查询不到,重新输入。
	
while(true){

	System.out.println("请您输入登录密码:");
	String password = scanner.next();
	//此处不能用account,要考虑到变量的作用域。变量从它声明的时候开始生效,直到它邻近的第一个"}"才失效。
	//这时要考虑这个account是在所有方法中都使用,还是只在当前方法内使用。
	//此处应该在login()方法开头提前声明变量account
	if(!password.equals(account.getPassword())) {
		//账户有误
		System.out.println("系统中不存在该账户卡号");
	}else{
		//密码正确
		break;
	}
	
}

	//4.提示登录成功信息
	System.out.println("恭喜您,"+account.getUsername()+",您已进入系统,您的卡号是:"+account.getCardId());
}


为了方便测试,要做两个模拟数据。
所以要在start()方法的开头,先向账户集合中插入两个模拟账户。
相当于系统启动的时候就有两个内部账号。


public void start(){
//todo 临时模拟,上线之前要删除
//系统启动的时候,先向账户集合中插入两个模拟账户
accountList.add("66666666","测试1","123",'男',100,100);
accountList.add("88888888","测试2","123",'女',100,100);
......
}

至此,登录功能已实现。
在这里插入图片描述

五、操作页展示、查询账户、退出账户

登录成功后应该展示的界面,即操作页。

//此时需要在ATM类的成员变量位置声明一个登录成功后的用户变量
public class ATM{
	......
	Account currentAccount = null;
	......
}


public void login(){

......

//3.接收用控制台输入的密码信息,使用提供的密码信息和刚才找到的账户中的密码比对,如果查询不到,重新输入。

//3.5这里需要将登录成功后的账户,登录成功之后,现将当前这个登录的账户保存到全局变量
	
	currentAccount = account;

//4.提示登录成功信息

......

public void login(){

	......

	//5.登录成功之后,进入操作页
	showOperationView();
}

g.showOperationView()方法

在这里插入图片描述

//登录成功之后,进入操作页,操作页提供登录成功之后的可选操作页
	public void showOperationView(){
	while(true){
	
		System.out.println("===" + currentAccount.getUsername()+",您可以办理以下业务===");
		System.out.println("1.查询账号");
		System.out.println("2.存款");
		System.out.println("3.取款");
		System.out.println("4.转账");
		System.out.println("5.修改密码");
		System.out.println("6.退出");
		System.out.println("7.注销账户");
		System.out.println("请选择:");
	
		String command = scanner.next();

		switch(command){
			case "1":
				//展示当前用户对象currentAccount属性打印在控制台
				showLoginAccount();
				break;
			case "2":
				depositMoney();//存款:本质是修改当前账户的money值
				break;
			case "3":
				drawMoney();//取款:本质是修改当前账户的money属性(要保证当次取款金额小于限额还有小于余额)
				break;
			case "4":
				transferMoney();//转账:本质是修改两个账户的余额(当前账户扣钱,对方账户加钱(校验身份:1.账户 2.身份 3.余额))
				break;
			case "5":
				updatePassword();//更新密码:本质是修改当前登录账户的password属性值
				break;
			case "6":
			//退出 showOperationView()——>login() break——>swtich——>while循环
				return;
			case "7":
				//销户操作:成功--欢迎页	失败--操作页面
				boolean flag = cancelAccount();
				if(flag){
					//销户成功,返回到欢迎页
					return;
				}else{
					//销户失败,留在操作界面
				}
				break;
			default:
				System.out.println("您输入的指令有误,请重新输入");
		}		
	}
}

接下来,需要写一个登录用户信息展示方法:

h.showLoginAccount()方法

//将当前登录用户对象currentAccount属性打印在控制台
System.out.println("====正在展示当前登录用户的信息====");
System.out.println("卡号:" + currentAccount.getCardId());

System.out.println("姓名:" + currentAccount.getUsername());

System.out.println("余额:" + currentAccount.getMoney());

System.out.println("单词提现限额:" + currentAccount.getLimit());


六、用户密码修改

在这里插入图片描述

i.updatePassword()方法

//更新密码:本质是修改当前登录账户的password属性值
public void updatePassword(){
while(true){
	System.out.println("====银行密码修改界面====");
	System.out.println("请输入当前账户的密码:");
	String oldPassword = scanner.next();
	
			//与当前登录用户的密码对比	
			if(!currentAccount.getPassword().equals(oldPassword)){
			//当前密码输入有误
			System.out.println("当前账户密码不正确");
		}else{
			while(true){
			
			//当前密码输入正确,应该输入新密码
			System.out.println("请您输入新密码");
			String password = scanner.next();
			System.out.println("请再次输入新密码以确认:");
			String password2 = scanner.next();
			//判断两次输入的新密码是否一致
			if(!password.equals(password2)){
				System.out.println("您两次输入的密码不一致,请重新输入");
			}else{
				//输入的密码无误,重新设置密码
				currentAccount.setPassword(password);
				//提示
				System.out.println("密码修改已成功。");
				
				}
				
			}
			
		}

	}
	
}

七、销户功能实现

销户操作:本质是从账户集合中删除当前登录账户

销户操作的基本需求:

在这里插入图片描述

cancelAccount()方法


//销户操作:本质是从账户集合中删除当前登录账户。
//在删除过程中判断:1.客户意愿2.是否有余额

private boolean cancelAccount(){
	//1.询问用户是否要销户,如果答案是否,直接返回false
	System.out.println("您真的要销户?y/n");
	String command = scanner.next();
	if(!command.equals("y")){
		System.out.println("销户操作终止!");
		return false;
	}
	
	//2.如果用户就是要销户,再判断是否有余额,如果有,提示无法销户,返回false
	if(currentAccount.getMoney() > 0) {
		System.out.println("您账户中还有钱没有取完,不允许销户!");
		return false;
	}

	//3.执行销户操作,提示销户操作成功,返回true
	accountList.remove(currentAccount);
	System.out.println("销户成功,即将跳转到登录页面");
	return true;
}

八、存款、取款功能实现

在这里插入图片描述

用户存款功能

存款操作的本质是:用户为自己的账户存钱,存钱后更新账户的余额。

depositMoney()方法
private void depositMoney(){
	System.out.println("===存款操作界面===");
	System.out.println("请您输入存款金额");
	//这个m不能是负数
	double m = scanner.nextDouble();//本次要存的金额

	//拿到要存的钱之后要添加到当前的余额上
	//1.先拿到当前账户的当前余额
	double money = currentAccount.getMoney();//账户查出来的金额

	//2.在当前余额的基础上加上本次要存的金额
	money = money + m;

	//3.将加后的余额保存回账户
	currentAccount.setMoney(money);//重新赋值

	//4.提示:存款成功
	System.out.println("存款成功!本次存款金额" + m + "存完之后当前余额" + currentAccount.getMoney());
	
	
}

用户取款功能

取款操作的本质是:从自己的账户中取钱。

取钱的要求:
1.需要先让用户输入取款金额
2.需要判断取款金额是否超过单词限额余额是否足够

drawMoney()方法
//取款:本质是修改当前账户的money属性(要保证当次取款金额小于限额还有小于余额)
private void drawMoney(){
	System.out.println("===取款操作界面===");
	System.out.println("请您输入取款金额");
	//这个m不能是负数
	double m = scanner.nextDouble();//本次要取的金额(键盘录入)

	//1.当次取款金额小于限额
	if(m > currentAccount.getLimit()){
		System.out.println("对不起,您的本次取款金额已经超出限额,无法完成取款操作");
		return;
	}
	//2.当次取款金额小于余额
		if(m > currentAccount.getMoney()){
		System.out.println("对不起,您的本次取款金额已经超出余额,无法完成取款操作");
		return;
		
	//3.执行取款操作(修改当前账户的money属性值)
	
	currentAccount.setMoney(currentAccount.getMoney()-m);
	
/*
	//1.先拿到当前账户的当前余额
	double money = currentAccount.getMoney();//账户查出来的金额

	//2.在当前余额的基础上减去本次要取的金额
	money = money - m;

	//3.将减后的余额保存回账户
	currentAccount.setMoney(money);//重新赋值
*/

	//4.提示:存款成功
	System.out.println("取款成功!本次取款金额" + m + "取款之后当前余额" + currentAccount.getMoney());

}

九、转账功能实现

转账:本质是修改两个账户的余额(当前账户扣钱,对方账户加钱(校验身份:1.账户 2.身份 3.余额))
在这里插入图片描述

transferMoney()方法

//转账:本质是修改两个账户的余额(当前账户扣钱,对方账户加钱(校验身份:1.账户 2.身份 3.余额))

private void transferMoney(){

	double money = 0;
	
	Account targetAccount = null;

	System.out.println("===转账操作界面===");
	//1.输入接收款项的账户id,检验id是否在本银行存在,若不存在,重新输入
	while(true){
	
		//1-1 接收卡号
		System.out.println("请输入对方账户:");
		String cardId = scanner.next();
		//1-2拿到卡号,根据卡号查询是否有账户
		targetAccount = findByCardId(cardId);
		if(targetAccount == null){
			//账户输错了,提示对方重输
			System.out.println("请输入的对方账户有误,请重新输入");
		}else{
			break;//输入正确,跳出循环
		}
	}
		
	//2.输入接收款项的账户的用户名姓氏,校验对方身份,若校验失败,重新输入
		//2-1获取对方的名和姓
		String username = targetAccount.getUsername();//林允儿
		String xing = username.substring(0,1);//林允儿——>林——>substring(0,1)
		String ming = username.substring(1);//林允儿——>允儿——>substring(1)
	while(true){
		System.out.println("您当前要为【*"+ming+"】转账");
		System.out.println("请您输入收款方姓氏");
		//2-2从键盘接收对方的姓氏
		String xingFromKeyBoard =  scanner.next();
		//2-3对比键盘接收的姓  vs  截取得到的姓
		if(!xingFromKeyBoard.equals(xing)) {
			System.out.println("对方姓氏输入有误,请重新输入");
		} else{
			//输入正确,跳出循环
			break;
		}//else
	}//while

	//3.接收键盘录入的转账金额,对金额也要进行判断(跟余额对比),若大于余额,重新输入
while(true){	
	System.out.println("请您输入转账金额");
	money = scanner.nextDouble();
	if(money<0  ||  money>currentAccount.getMoney()){
		System.out.println("请您输入的转账金额有误,请重新输入");
	}else{
		break;
	}
}
	//4.执行转账操作,给出操作成功提示
		//4-1对方账户加钱
		targetAccount.setMoney(targetAccount.getMoney() + money);
		
		//4-2自己账户减钱
		currentAccount.setMoney(currentAccount.getMoney() - money);
		
		//4-3给出成功提示
		System.out.println("恭喜您转账成功,本次转账金额"+money+",当前账户余额:"+currentAccount.getMoney());
}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你小汁完了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值