JAVA-

目录

# day01.[环境变量,HelloWorld]

# 第一章 Java概述 

## 1.1 JavaSE课程体系介绍

## 1.2 计算机语言介绍(了解)

## 1.3 Java语言概述(了解)

## 1.4 什么是软件开发

# 第二章.Java语言前言

## 1.字节

## 2.常用的dos命令

# 第三章.Java所需要的环境

## 1.jvm和跨平台

day3

#  模块二.变量  数据类型转换   运算符

# 模块三 idea_运算符

# 第一章.IDEA的使用

## 3.赋值运算符

1.基本赋值运算符

2.复合赋值运算符:

3.注意:byte short 遇到复合赋值运算符,jvm会自动转型      

## 4.关系运算符(比较运算符)

## 5.逻辑运算符

## 6.三元运算符

### 6.1练习1(需求):小明考完试了,判断小明的分数是否及格,返回结果

### 6.2练习2:有两个老人,年龄分别为70  80  求出两个老人的最高年龄

### 6.3 练习3:有三个老人,年龄分别为70  80  60  求出三个老人的最高年龄

day4

# 模块四_流程控制


# day01.[环境变量,HelloWorld]

```java
1.会常用的dos命令
2.会安装java所需要的环境(jdk)
3.会配置java的环境变量
4.知道java开发三步骤
5.会java的入门程序(HelloWorld)
6.会三种注释方式
7.知道Java入门程序所需要注意的地方
8.知道println和print的区别
```

# 第一章 Java概述 

## 1.1 JavaSE课程体系介绍

JavaSE知识图解

![1561379629326](img/JavaSE课程内容介绍.png)

JavaSE知识模块介绍

* **第一部分:计算机编程语言核心结构:**`数据类型`、`运算符`、`流程控制`、`数组`、…  

  (没有为啥,按照格式定义)

* **第二部分:Java面向对象核心逻辑:**`类和对象`、`封装`、`继承`、`多态`、`抽象`、`接口`、…

  JAVA核心编程思想(面向对象),很多功能别人已经给我们实现好了,我们直接调用这个对象的功能就可以了,

  让代码变得简单了,简洁了

* **第三部分:JavaSE核心高级应用:**`集合`、`I/O`、`多线程`、`网络编程`、`反射机制`、…

* **第四部分:Java新特性:**`Lambda表达式`、`函数式编程`、`新Date/Time API`、`接口的默认、静态和私有方法`、…  

* **第五部分:MySQL/JDBC核心技术:**`SQL语句`、`数据库连接池`、`DBUtils`、`事务管理`、`批处理`、…

## 1.2 计算机语言介绍(了解)

### 计算机编程语言是什么

所谓计算机编程语言,就是人们使用编程语言对计算机下达的命令,让计算机完成人们需要的功能。

```java
翻译:所谓的计算机编程语言,就是计算机能看懂的语言,我们需要学习这些计算机编程语言,给计算机下达指令,让计算机给我们完成一些功能
```

### 计算机语言发展

* 第一代:机器语言(计算机很庞大,都是0和1组成的指令,而且需要同时按下多个键才能完成一个指令,而且用0和1组成的一个一个指令,所以工程师们就要记住0和1的各种组合以及对应的指令)

* 第二代:汇编语言(面向机器的语言,因为直接面对机器需要记一些 0 和1 的指令,很痛苦,所以就出现了很多助记词,比如:add.汇编语言现在还在使用,接近于机器语言,越接近机器语言,速度越快,而且最终还是转成0和1存储)

* 第三代:高级语言(更接近我们人类语言,常见的有很多,比如C语言,java等)

  ```java
  不管是第几代语言,最终都会向0和1靠近,因为CPU只认识0和1
  电脑上所有的内容,都是通过CPU将0和1转换而来的    
  ```

### 计算机语言排行榜

![image-20201109084739737](img/image-20201109084739737.png)

### 计算机语言走势

![image-20200820180851296](img/image-20200820180851296.png)

## 1.3 Java语言概述(了解)

### Java生态圈

**Java是目前应用最为广泛的软件开发平台之一。**随着Java以及Java社区的不断壮大,Java 也早已不再是简简单单的一门计算机语言了,它更是一个平台、一种文化、一个社区。

**作为一个平台,**Java虚拟机扮演着举足轻重的作用。除了 Java语言,任何一种能够被编译成字节码的计算机语言都属于Java这个平台。Groovy、Scala、 JRuby、Kotlin等都是Java平台的一部分,它们依赖于Java虚拟机,同时,Java平台也因为它们变得更加丰富多彩。而且Java还可以跨平台

**作为一种文化,**Java几乎成为了 “开源”的代名词。在Java程序中,有着数不清的开源软件和框架。如Tomcat、Struts, Hibernate, Spring,MyBatis等。就连JDK和JVM自身也有不少开源的实现,如OpenJDK、Apache Harmony。可以说,“共享”的精神在Java世界里体现得淋漓尽致。

**作为一个社区,**Java拥有全世界最多的技术拥护者和开源社区支持,有数不清的论坛和资料。从桌面应用软件、嵌入式开发到企业级应用、后台服务器、中间件,都可以看到Java的身影。其应用形式之复杂、参与人数之众多也令人咋舌。可以说,Java社区已经俨然成为了一个良好而庞大的生态系统。**其实这才是Java最大的优势和财富。**

### Java 是最好的语言吗?

不是,因为在每个领域都有更合适的编程语言。

- C 语言无疑是现代计算机软件编程语言的王者,几乎所有的操作系统都是 C 语言写成的。C里面有一个编译器,会将系统软件变成机器语言,让硬件识别,和硬件做交互.C++ 是面向对象的 C 语言,一直在不断的改进。


- JavaScript 是能运行在浏览器中的语言,丰富的前端界面离不开 Javascript 的功劳。近年来的 Node.js 又在后端占有一席之地。
- Python 用于系统管理,并通过高性能预编译的库,提供 API 来进行科学计算,文本处理等,是 Linux 必选的解释性语言。现在Python也被用于web开发、科学计算和统计、人工智能、网络爬虫等
- Ruby 强于 DSL(领域特定语言),程序员可以定义丰富的语义来充分表达自己的思想。
- Erlang 就是为分布式计算设计的,能保证在大规模并发访问的情况下,保持强壮和稳定性。
- Go 语言内置了并发能力,可以编译成本地代码。当前新的网络相关项目,很大比例是由 Go 语言编写的,如 Docker、Kubernetes 等。
- 编写网页用 PHP,函数式编程有 Lisp,编写 iOS 程序有 Swift/Objective-C。
- R的思想是:它可以提供一些集成的统计工具,但更大量的是它提供各种数学计算、统计计算的[函数](https://baike.baidu.com/item/函数/301912),从而使使用者能灵活机动的进行数据分析,甚至创造出符合需要的新的统计计算方法 
- SQL 是用于访问和处理数据库的标准的计算机语言, 这类数据库包括:MySQL,Oracle, Sybase, SQL Server, DB2, Access 等等 


一句话概括,**能留在排行榜之上的语言,都是好的语言,在其所在的领域能做到最好。**

### Java语言发展历史

Java诞生于SUN(Stanford University Network),09年SUN被Oracle(甲骨文)收购。

Java之父是詹姆斯.高斯林(James Gosling)。

![1615793633189](img/1615793633189.png)

**詹姆斯·高斯林**等人于1990年代初开发Java语言的雏形,最初被命名为**Oak**,目标设置在**家用电器等小型系统的程序语言**,应用在**电视机、电话、闹钟、烤面包机**等家用电器的**控制和通信**。由于这些智能化家电的市场需求没有预期的高,Sun公司放弃了该项计划。随着1990年代互联网的发展,Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。

1996年发布JDK1.0版。

目前最新的版本是Java17。我们学习的Java8以及jdk17。

|   发行版本    |  发行时间  |                             备注                             |
| :-----------: | :--------: | :----------------------------------------------------------: |
|     Java      | 1995.05.23 |     Sun公司在Sun world会议上正式发布Java和HotJava浏览器      |
|   Java 1.0    | 1996.01.23 |             Sun公司发布了Java的第一个开发工具包              |
|   Java 1.1    | 1997.02.19 |                                                              |
|   Java 1.2    | 1998.12.08 |    拆分成:J2SE(标准版)、J2EE(企业版)、J2ME(小型版)    |
|   Java 1.3    | 2000.05.08 |                                                              |
|    Java1.4    | 2004.02.06 |                                                              |
| **Java 5.0**  | 2004.09.30 | ①版本号从1.4直接更新至5.0;②平台更名为JavaSE、JavaEE、JavaME |
|   Java 6.0    | 2006.12.11 |               2009.04.20 Oracle宣布收购SUN公司               |
|   Java 7.0    | 2011.07.02 |                                                              |
| **Java 8.0**  | 2014.03.18 |                                                              |
|   Java 9.0    | 2017.09.22 |    ①每半年更新一次;②Java 9.0开始不再支持windows 32位系统    |
|   Java 10.0   | 2018.03.21 |                                                              |
| **Java 11.0** | 2018.09.25 |           JDK安装包取消独立JRE安装包,长期支持版本           |
|   Java 12.0   | 2019.03.19 |                                                              |
|   Java 13.0   | 2019.9.18  |                                                              |
|   Java 14.0   | 2020.3.17  |                                                              |

```java
Google和Oracle的侵权事件:

Google 和 Oracle 纠缠多年的“Java 侵权案”又有了新的判决结果。Google 在此次对决中败诉,并可能需要支付高达88亿美元的赔偿金。这个案件还引发关于 API(应用程序编程接口)是否应该受版权保护的争议。

其实早在2010年8月,Oracle 就已经向法院起诉 Google 侵权,声称 Google 在开发 Android 平台时未经授权就使用了 Oracle 的 Java 应用编程接口数据包。

另外,虽然 Google 当年为避免版权问题而重写了 Java API,却意外地使用了和 Oracle JDK 相同的一小段代码,这使得 Google 陷入不利的局面。

正是由于 Google 在 Android 平台上使用 Java 时并未和 Sun 公司达成授权协议,造成了巨大的隐患,尤其是在 Oracle 收购 Sun 公司之后。
```

![1615793545482](img/1615793545482.png)

### Java技术体系平台

* JavaSE(Java Platform, Standard Edition标准版):允许您在桌面和服务器上开发和部署Java应用程序。Java提供了丰富的用户界面、性能、多功能性、可移植性和当今应用程序所需的安全性。
* JavaEE(Java Platform, Enterprise Edition企业版):是为开发企业环境下的应用程序提供的一套解决方案,主要针对于Web应用程序开发。
* JavaME(Java Platform, Micro Edition 小型版):为互联网上的嵌入式和移动设备上运行的应用提供了一个健壮、灵活的环境:微控制器、传感器、网关、移动电话、个人数字助理(PDA)、电视机顶盒、打印机等等。JavaME包括灵活的用户界面、健壮的安全性、内置的网络协议,以及支持动态下载的网络和离线应用程序。基于JavaME的应用程序在许多设备上都是可移植的,但是利用了每个设备的本机功能。
  *  Java Embedded(Im'bedId): 用于解锁物联网的智能设备的价值:
     通过远程市场更新和刷新功能延长产品生命周期和价值;
     利用Java的可伸缩性、健壮性、可移植性和全套功能,提高生产效率,降低成本,缩短上市时间;
     在边缘启用快速数据功能;
  *  Java Card:使安全元件(如智能卡和其他防篡改安全芯片)能够承载采用Java技术的应用程序。Java card提供了一个安全的、可互操作的执行平台,它可以在一个资源受限的设备上存储和更新多个应用程序,同时保持最高的认证级别和与标准的兼容性。
  *  Java TV:是一种基于JavaME的技术,它为开发在tv和机顶盒设备上运行的java应用程序提供了一个性能良好、安全且易于实现的解决方案。使用Java TV运行时,开发人员可以轻松创建应用程序,例如电子节目指南(EPG)、视频点播(VOD)客户端、游戏和教育应用程序、用于访问Internet数据的应用程序(例如天气、新闻播报器、社交网络)以及大多数蓝光光盘标题上的用户界面和奖金内容。

## 1.4 什么是软件开发

```java
1.概述:
  软件开发是根据用户要求建造出软件系统或者系统中的软件部分的过程
  软件开发是一项包括需求捕捉、需求分析、设计、实现和测试的系统工程
  软件一般是用某种程序设计语言来实现的。通常采用软件开发工具可以进行开发
  
2.我们将来主要从事软件开发中各个环节的哪个环节呢?实现
  
3.我们将来主要用什么程序设计语言来开发呢? java语言 sql语言  js
```

# 第二章.Java语言前言

## 1.字节

```java
1.字节:计算机中存储数据的最小存储单元(计量单位),用byte或者B表示
  二进制位:用bit(比特)表示
  8个二进制位代表一个字节 
      
      
2.存储单元之间的转换:
  8bit = 1B
  1024B = 1KB
  1024KB = 1MB
  1024MB = 1GB
  1024GB = 1TB
      
  PB   EB  ZB ...    
```

<img src="img/1698284758661.png" alt="1698284758661" style="zoom:80%;" />

## 2.常用的dos命令

```java
1.打开dos命令窗口:
  win+r -> 输入cmd -> 回车
```

<img src="img/1698285433042.png" alt="1698285433042" style="zoom:80%;" />

<img src="img/1698285568344.png" alt="1698285568344" style="zoom:80%;" />

| 作用                           | 命令                                                         |
| ------------------------------ | ------------------------------------------------------------ |
| 切换盘符                       | 盘符名: -> 回车<br>盘符名不区分大小写,但是计算机上必须有指定的盘符 |
| 查看当前路径下的文件或者文件夹 | dir                                                          |
| 进入到指定文件夹下             | cd 文件夹名字                                                |
| 进入到多级文件夹下             | cd 文件夹名字\文件夹名字                                     |
| 退到上一级目录                 | cd..或者 cd ..                                               |
| 直接退到磁盘位置(退到根目录)   | cd\或者cd \                                                  |
| 清屏                           | cls                                                          |
| 退出黑窗口                     | exit                                                         |
| 创建文件夹                     | mkdir 文件夹名                                               |
| 创建多级文件夹                 | mkdir 文件夹名\文件夹名                                      |
| 删除文件夹                     | rd 文件夹名<br>注意:删除的文件夹必须是空的<br>不走回收站     |
| 删除文件                       | del 文件名.后缀名<br>不走回收站                              |
| 批量删除文件                   | del *.后缀名                                                 |

> 1.如何区分正斜杠和反斜杠:
>
>    /:正斜杠
>
>   \:反斜杠
>
> 2.快速打开该目录对应的dos命令窗口:
>
>    a.选中路径
>
>    b.输入cmd -> 回车
>
> 3.按上下箭头,切换之前输入过的命令
>
> 4.在dos命令窗口中,可以输入文件夹名或者文件名的一部分,按 -> tab键 -> 自动补全文件夹名或者文件名

# 第三章.Java所需要的环境

## 1.jvm和跨平台

```java
1.jvm(java虚拟机):java运行程序的假想计算机,主要用来运行java程序的
2.跨平台:java代码可以在不同的操作系统上运行(一次编写,到处运行)
  跨:跨越
  平台:操作系统 -> windows linux mac os  
      
3.关系:java程序想要在不同的操作系统上运行,实现跨平台,就需要安装不同版本的jvm      
```

<img src="img/1698304141613.png" alt="1698304141613" style="zoom:80%;" />

## 2.JDK和JRE

```java
1.jdk:(Java Development Kit):java开发工具包,包含了jre
  javac 编译工具
  java 运行工具
  jdb  调试工具
  jhat 内存分析工具
  ...  
2.jre:(Java Runtime Environment):java运行环境,包含了jvm以及后面开发用到的核心类库
    
3.jdk和jre以及jvm的关系:
  jdk包含了jre,jre包含了jvm,所以我们只需要安装jdk即可
```

> 但是从jdk9开始jdk目录中就没有单独的jre目录了,因为jre作为一个运行时,里面不需要包含太多的东西浪费空间,降低运行效率,在jdk9的时候引用模块化的技术,让开发者能按照自己的应用创建一个最小的运行时(比如一个微服务的部署应用仅仅需要一个非常小的runtime,而不是像以前一样不管应用复杂还是简单,都需要一个近百兆的jre运行)这样提高了运行效率

### 2.1.jdk安装

```java
1.下载:www.oracle.com
```

<img src="img/1698306463672.png" alt="1698306463672" style="zoom:80%;" />

```java
 1.安装:双击 -> 选择安装路径(安装路径上不要有中文,不要有空格)
 2.一定要记住:以后所有开发相关的安装路径上都不要有中文和空格    
```

<img src="img/1698306706203.png" alt="1698306706203" style="zoom:80%;" />

> 测试:进入到jdk的bin路径下,打开对应dos命令窗口
>
> 输入javac(编译命令)和java(运行命令)

### 2.2.环境变量的配置

```java
1.问题:将来我们需要创建一个java文件写代码,然后编译和运行的时候需要打开此java文件所在的目录,java文件的目录如果和javac以及java命令所在的bin目录不一致,那么javac和java命令就用不了了,毕竟javac和java命令在bin目录下,所以难道我们将来必须将所有的java文件都放到bin目录下吗?
  那么我们能不能在任意目录下都能使用javac和java命令呢?能,需要配置环境变量
    
2.配置环境变量的目的:在任意路径下都可以随意使用javac和java命令进行对java代码的编译和运行    
```

```java
方式1:直接将jdk的bin路径粘贴到path中 -> 不推荐
```

<img src="img/1698308025548.png" alt="1698308025548" style="zoom:80%;" />

```java
方式2:极力推荐
     配置JAVA_HOME
```

<img src="img/1698308481783.png" alt="1698308481783" style="zoom:80%;" />

> jdk安装之后,自带环境变量配置->javapath(可以删除)->推荐使用JAVA_HOME
>
> 可能出现的问题:电脑重启之后,环境变量失效了
>
>    1.解决问题1:点到环境变量中,啥都不要做,直接点一下确定
>
>    2.解决问题2:直接将bin路径粘进去
>
> 当然,后面学了idea之后,不会出现这种问题了

# 第四章.Java第一个程序的开发

## 1.开发三步骤

```java
1.编写:
  a.创建一个文本文档,将后缀名改成.java,变成一个java文件
  b.注意:我们需要将文件的后缀名显示出来  
      
2.编译:
  a.命令:javac java文件名.java
  b.注意:javac会将java文件编译,生成一个.class文件(字节码文件),jvm运行只认class文件
      
3.运行:
  a.命令:java class文件名(不需要带后缀名了)
```

<img src="img/1698310112286.png" alt="1698310112286" style="zoom:80%;" />

## 2.编写HelloWorld

```java
public class Demo01HelloWorld{
    public static void main(String[] args){
        System.out.println("HelloWorld");
    }
}
```

```java
编译:
  javac java文件名.java
```

```java
运行:
  java class文件名(不要带后缀名了)
```

<img src="img/1698310705311.png" alt="1698310705311" style="zoom:80%;" />

## 3.注释

```java
1.概述:对代码的解释说明
2.分类:
  a.单行注释:
    //注释内容

  b.多行注释:
    /*
      注释内容
    */

  c.文档注释:
    /**
      注释内容
    */
```

```java
//单行注释 class后面的名字要和java文件名一致
public class Demo01HelloWorld{
    /*
      多行注释:
        main是一个方法,是程序的入口,jvm运行程序要找main当入口
        执行程序
    */
    public static void main(String[] args){
        /**
          文档注释:
            下面的语句是输出语句
        */
        System.out.println("HelloWorld");
    }
}
```

```java
1.文档注释作用:将来我们给别人一个开发好的类,如何让别人快速对我们写的代码了解呢?
  我们的文档注释中的内容可以根据javadoc命令生成一个文档(API文档)
  别人拿到这个文档,就能快速对此类以及类中实现的功能,进行快速了解
    
2.命令:javadoc -d 要生成的文件夹名字 -author -version 文件名.java    
```

```java
/**
  此类是一个java的入门程序
  @author 涛哥
  @version v1.0
*/
public class Demo02HelloWorld{
    /**
      main是一个方法,是程序的入口
      jvm执行java代码,都是从main方法开始执行
    */
    public static void main(String[] args){
        System.out.println("helloworld");
    }
}
```

> 1.右键中没有创建文件或者文件夹的选项 -> 所在的磁盘有权限问题
>
> 2.右键盘符 -> 属性 -> 安全 -> 编辑 -> 修改权限(完全控制)

## 4.第一个Java程序中每一句话的解释以及注意事项

```java
/*
  1.public class Demo03HelloWorld:定义一个类
  2.class:代表的就是类,类是java程序最基本的组成单元,所有代码都需要在类中写
  3.class后面跟的名字叫做类名,类名要和java文件名保持一致
*/
public class Demo03HelloWorld{
    /*
      public static void main(String[] args)
      叫做main方法,是程序的入口
      jvm执行代码,会从main方法开始执行
    */
    public static void main(String[] args){
        //打印语句(输出语句),会将我们想要输出的内容打印到控制台上
        System.out.println("helloworld");
    }
}
```

```java
注意事项:
  1.类名要和java文件名保持一致
  2.程序中的标点符号必须是英文的  
  3.不要将main写成mian
  4.System和String的首字母s要大写
  5.每个单词写完来个空格增强代码的可读性
  6.括号要一对一对的写
  7.代码写完语句用;代表结束了,一句话来个分号,证明这是一个单独的语句    
```

<img src="img/1698316431980.png" alt="1698316431980" style="zoom:80%;" />

<img src="img/1698316471785.png" alt="1698316471785" style="zoom:80%;" />

## 6.关键字

```java
1.关键字:java提前定义好的,具有特殊含义的小写单词
2.怎么记:不用提前都背下来,关键字在高级记事本中颜色特殊,学到哪里记到哪里    
```

<img src="img/1698317329001.png" alt="1698317329001" style="zoom:80%;" />

## 7.编写HelloWorld时要注意的问题

### 7.1字符编码问题

```java
1.编码:保存数据的过程就是编码的过程
2.解码:读数据的过程就是解码的过程
3.注意:
  a.编码和解码遵守的编码规范必须是一样的
  b.常见的两个编码规范:
    GBK:专门为我们中文所设计的编码
        ANSI代表的是GBK
        
        一个中文汉字在GBK中占2个字节
        
    UTF-8:一个中文汉字在UTF-8中占3个字节
        
  c.dos命令窗口默认编码:GBK       
```

<img src="img/1698318579697.png" alt="1698318579697" style="zoom:80%;" />![1698318655020](img/1698318655020.png)

### 7.2源文件名(java文件名)与类名一致问题?

```java
1.类名必须要和java文件名一致嘛?
  不是必须的
    
  如果类名和java文件名不一致,需要将class前面的public干掉
    
2.如果class前面带public,此时类名必须要和java文件名一致
    
3.一个java文件中可以写多个class类,但是只能有一个类带public
    
  但是建议不要随意在一个java文件中写多个class -> 一个java文件中就写一个class,而且带public的
    
4.main方法必须写在带public的类中    
```

> 小结:
>
>  1.一个java文件只写一个class,而且带public
>
>  2.类名和java文件名保持一致
>
>  3.main方法写在带public的类中

## 9.println和print区别

```java
相同点:都是输出语句
不同点:
  a.println:输出之后自带换行效果
  b.print:输出之后不带换行效果    
```

```java
public class Demo05HelloWorld{
    public static void main(String[] args){
        //System.out.println("床前明月光");
        //System.out.println("疑是地上霜");
        //System.out.println("举头望明月");
        //System.out.println("低头思故乡");
        System.out.print("床前明月光");
        System.out.print("疑是地上霜");
        System.out.print("举头望明月");
        System.out.print("低头思故乡");
        
    }
}

```

> 小技巧:
>
>   1.复制当前行:ctrl+d
>
>   2.一次操作多行:
>
> ​     a.预留出足够的空间
>
> ​     b.按住alt不放,鼠标往下拉,此时发现光标变长了

day3

#  模块二.变量  数据类型转换   运算符

```java
1.字节:计算机存储数据的最小存储单元(byte或者B)
  8bit = 1B -> 往后都是1024
2.常用的dos命令
  a.切换盘符   盘符名:
  b.查看       dir
  c.进入指定文件夹   cd 文件夹名     cd 文件夹名\文件夹名
  d.退到上一级   cd..
  e.退到根目录   cd\
  f.清屏      cls
  g.退出黑窗口   exit
  h.创建文件夹   mkdir 文件夹名      mkdir 文件夹名\文件夹名
  i.删除文件夹   rd 文件夹名     被删除的文件夹必须是空的,删除之后不走回收站
  j.删除文件     del 文件名.后缀名       del *.后缀名
      
3.jdk和jre以及jvm关系
  jdk包含jre,jre包含jvm
      
4.jvm和跨平台
  想要实现跨平台,就需要在不同的操作系统上安装不同版本的jvm
      
5.环境变量 -> JAVA_HOME
      
6.程序入门
  a.编写:
    public class 类名{
        public static void main(String[] args){
            System.out.println("helloworld");
        }
    }
  b.编译:
    javac java文件名.java
  c.运行:
    java class文件名
        
7.注释:对代码的解释说明
  单行注释: //
  多行注释: /**/
  文档注释: /***/

8.关键字:java提前定义好的,具有特殊含义的小写单词,在高级记事本中颜色特殊
    
9.常见问题
  a.编码问题:写代码以及运行遵守的编码要一致
  b.java文件名和类名一致问题
    带public的类类名要和java文件名一致
    一个java文件中最好写一个类
     
      
10.println和print区别
   相同点:都是输出语句
   不同点:println自带换行效果,print不带换行效果
       
第二大模块重点:常量 变量 类型转换 进制的转换
  1.常量的使用
  2.变量的使用
  3.会强制类型转换
```

# 第一章.常量

```java
1.概述:在代码的运行过程中,值不会发生改变的数据
2.分类:
  整数常量:所有整数
  小数常量:所有带小数点的
          2.5  1.5  2.0
  字符常量:带单引号的 ''  单引号中必须有且只能有一个内容
          '1'(算)   '11'(不算)   ''(不算)  'a1'(不算)
          ' '(算)   '  '(两个空格不算)
          '写一个tab键'(算)
      
  字符串常量:带双引号的 ""  双引号中内容随意
            ""   "helloworld"

  布尔常量:true(真) false(假) -> 这两个单词不要加双引号
          "true"(这样写属于字符串,不属于布尔常量)
      
  空常量:null  代表的是数据不存在    
```

```java
public class Demo01Constant{
    public static void main(String[] args){
        //整数常量
        System.out.println(1);
        System.out.println(-1);
        
        //小数常量
        System.out.println(1.5);
        System.out.println(1.0);
        
        //字符常量   单引号中必须有且只能有一个内容
        System.out.println('1');
        //System.out.println('11');错误
        System.out.println(' ');//一个空格算一个内容
        //System.out.println('    ');//四个空格算四个内容,所以不属于字符常量
        System.out.println('    ');//tab键算一个内容
        
        //字符串常量
        System.out.println("本人是尚硅谷第一帅的男人");
        System.out.println("");
        
        //布尔常量
        System.out.println(true);
        System.out.println(false);
        
        //空常量 不能直接使用
        //System.out.println(null);
    }
}
```

```java
public class Demo02Constant{
    public static void main(String[] args){
        System.out.println(10+3);//13
        System.out.println(10-3);//7
        System.out.println(10*3);//30
        /*
          /前后如果都是整数,结果只取整数部分
          
          /前后只要有一个数带小数点,结果就是正常小数了
        */
        System.out.println(10/3);//3
        System.out.println(10.0/3);
        System.out.println(10/3.0);
    }
}
```

<img src="img/1698392299314.png" alt="1698392299314" style="zoom:80%;" />

# 第二章.变量

| 数据类型     | 关键字         | 内存占用 | 取值范围                                                     |
| :----------- | :------------- | :------- | :----------------------------------------------------------- |
| 字节型       | byte           | 1个字节  | -128 至 127  定义byte变量时超出范围,废了                     |
| 短整型       | short          | 2个字节  | -32768 至 32767                                              |
| 整型         | int(默认)    | 4个字节  | -2^31^ 至 2^31^-1  正负21个亿<br>-2147483648——2147483647     |
| 长整型       | long           | 8个字节  | -2^63^ 至 2^63^-1   19位数字<br>-9223372036854775808到9223372036854775807 |
| 单精度浮点数 | float          | 4个字节  | 1.4013E-45 至 3.4028E+38                                     |
| 双精度浮点数 | double(默认) | 8个字节  | 4.9E-324 至 1.7977E+308                                      |
| 字符型       | char           | 2个字节  | 0 至 2^16^-1                                                 |
| 布尔类型     | boolean        | 1个字节  | true,false(可以做判断条件使用)                              |

## 1.变量的介绍以及使用

```java
1.变量的数据类型:
  基本数据类型:4类8种
      整型:byte short int long
      浮点型:float double
      字符型:char
      布尔型:boolean
          
  引用数据类型: 类 数组 接口 枚举 注解
      
2.概述:在代码的运行过程中,值会随着不同的情况而随时发生改变的数据
    
3.作用:一次接收一个数据
       将来定义一个变量,接收一个值,后续可能会根据不同的情况对此值进行修改,此时可以用变量
    
4.定义:
  a.数据类型 变量名 = 值;

  b.数据类型 变量名;
    变量名 = 值;

  c.连续定义三个相同类型的变量
    数据类型 变量名1,变量名2,变量名3;
    变量名1 = 值;
    变量名2 = 值;
    变量名3 = 值;

    比如:int i,j,k;
         i = 10;
         j = 20; 
         k = 30;


    数据类型 变量名1 = 值,变量名2 = 值,变量名3 = 值;
    比如: int i = 10,j = 20,k = 30;

    正确读法:先看等号右边的,再看等号左边的 -> 将等号右边的数据赋值给等号左边的变量
            哪怕等号右边有运算,我们都得先将等号右边的运算算出一个值来,最后赋值给等号左边的变量
        
5.注意:
  a.字符串不属于基本数据类型,属于引用数据类型,用String表示
    String是一个类,只不过字符串在定义的时候可以和基本数据类型格式一样
      
6.float和double的区别:
  a.float的小数位只有23位二进制,能表示的最大十进制为2的23次方(8388608),是7位数,所以float型代表的小数,小数位能表示7位
      
  b.double的小数位只有52位二进制,能表示的最大十进制为(4 503 599 627 370 496),是16位数,所以double型代表的小数,小数位能表示出16位
      
      
7.切记:将来开发不要用float或者double直接参与运算,因为直接参与运算会有精度损失问题    
```

```java
public class Demo03Var{
    public static void main(String[] args){
        //byte
        byte num1 = 100;
        System.out.println(num1);
        
        //short
        short num2 = 1000;
        num2 = 1001;
        System.out.println(num2);
        
        //int  整数的默认类型
        int num3 = 10000;
        num3 = 1;
        System.out.println(num3);
        
        //long -> 定义long型的变量后面加个L
        long num4 = 10L;
        System.out.println(num4);
        
        //float -> 定义float型变量的时候后面加个F
        float num5 = 2.5F;
        System.out.println(num5);
        
        //double -> 小数的默认类型
        double num6 = 2.5;
        System.out.println(num6);
        
        //char
        char num7 = 'A';
        System.out.println(num7);
        
        //boolean
        boolean num8 = true;
        boolean num9 = false;
        
        /*
           num9 = false
           num8 = num9 -> 将num9的值赋值给num8 -> 相当于num8 = false
        */
        num8 = num9;
        System.out.println(num8);
        
        //String -> 是一个引用数据类型,属于类的一种,但是定义和基本类型一致
        String name = "金莲";
        System.out.println(name);
    }
}
```

```java
public class Demo04Var{
    public static void main(String[] args){
        int num1 = 10;
        int num2 = 3;
        
        int sum = num1+num2;
        System.out.println(sum);//13
        
        int sub = num1-num2;
        System.out.println(sub);//7
        
        //System.out.println(num1*num2);//30
        int mul = num1*num2;
        System.out.println(mul);//30
        
        /*
          由于/前后都是整数,结果取整数部分,结果还赋值给一个整数变量
        */
        int div = num1/num2;
        System.out.println(div);//3
        
        double div1 = num1/num2;//3.0
        System.out.println(div1);
    }
}
```

```java
public class Demo05Var{
    public static void main(String[] args){
        /*
          转义字符:  \
          
          可以这样简单理解:
            a.将普通字符转成具有特殊含义的字符
            b.将具有特殊含义的字符转成普通字符
        
        */
        
        
        /*
           n:普通字符
           \n:换行符
        */
        
        System.out.print("春眠不觉晓\n");
        System.out.print("处处闻啼鸟\n");
        System.out.print("夜来风雨声\n");
        System.out.print("花落知多少\n");
        
        /*
           t:普通字符
           \t:制表符 -> 就是tab键
        */
        System.out.println("本人\t是尚硅谷第一帅");
        
        
        /*
          用String表示一个路径
          在java中两个\\代表一个\
        */
        
        String path = "E:\\01_javase_video\\code";
        System.out.println(path);
    }
}
```

```java
public class Demo06Var{
    public static void main(String[] args){
        float a = 10;
        float b = 3;
        
        float result = a/b;
        System.out.println(result);//3.3333333
        
        
        double c = 10;
        double d = 3;
        double result02 = c/d;
        System.out.println(result02);//3.3333333333333335
        
        
        float x = 3.55F;
        float y = 2.12F;
        
        float result03 = x-y;
        System.out.println(result03);//1.4300001
        
    }
}
```

## 2.变量使用时的注意事项

```java
1.变量不初始化(第一次赋值)不能直接使用
2.在同一个作用域(一对大括号就是一个作用域)中不能定义重名的变量 
3.不同作用域中的数据尽量不要随意互相访问
  在小作用域中能直接访问大作用域中的变量
  在大作用域中不能直接访问小作用域中的变量
```

```java
public class Demo07Var{
    public static void main(String[] args){
        int i = 10;
        System.out.println(i);
        
        int j;
        
        j = 10;
        System.out.println(j);
        
        int k = 10;
        //int k = 20;//只要是变量名前带具体的数据类型就是重新定义
        System.out.println(k);
        
        {
           int x = 1000;
           System.out.println(k);           
        }
        
        //System.out.println(x);    
        
    }
}
```

## 3.练习

```java
定义一个人类,用变量表示 姓名 性别 年龄 身高 体重
```

```java
public class Demo08VarPerson{
    public static void main(String[] args){
        //姓名
        String name = "张三";
        //性别
        char sex = '男';
        //年龄
        int age = 20;
        //身高
        double height = 175.5;
        //体重
        double weight = 145.5;
        
        System.out.println(name);
        System.out.println(sex);
        System.out.println(age);
        System.out.println(height);
        System.out.println(weight);
    }
}
```

# 第三章.标识符

```java
1.概述:咱们给类,方法,变量取的名字
2.注意:
  a.硬性规定(必须遵守)
    标识符可以包含"英文字母","数字","$和_"
    标识符不能以数字开头  int i1 = 100(正确)  int 1i = 100(错误)
    标识符不能是关键字  int static = 100(错误)   int public = 100(错误)
      
  b.软性建议(可遵守可不遵守,但是建议遵守)
    给类取名字:遵循大驼峰式 -> 每个单词首字母大写
    给方法和变量取名字:遵循小驼峰式 -> 从第二个单词开始往后首字母大写
   
    见名知意
```

# 第四章.数据类型转换

```java
1.什么时候发生类型转换:
  a.等号左右两边类型不一致
  b.不同类型的数据做运算
      
2.分类:
  a.自动类型转换
    将取值范围小的数据类型赋值给取值范围大的数据类型 -> 小自动转大
    取值范围小的数据类型和取值范围大的数据类型数据做运算 -> 小自动转大
      
  b.强制类型转换
    当将取值范围大的数据类型赋值给取值范围小的数据类型 -> 需要强转
      
3.基本类型中按照取值范围从小到大排序:
  byte,short,char -> int -> long -> float -> double     
```

## 1.自动类型转换

```java
1.将取值范围小的数据类型赋值给取值范围大的数据类型 -> 小自动转大
2.取值范围小的数据类型和取值范围大的数据类型做运算 -> 小自动转大    
```

```java
public class Demo09DataType{
    public static void main(String[] args){
        /*
          等号右边是整数,整数默认类型为int
          等号左边是long型的变量
          
          将取值范围小的数据类型赋值给取值范围大的数据类型,发生了自动类型转换
        */
        long num1 = 100;
        System.out.println(num1);
        
        
        int i = 10;
        double b = 2.5;
        
        /*
           double = int+double
           double  = double+double
           int自动提升为了double,发生了自动类型转换
        */
        double sum = i+b;
        System.out.println(sum);
    }
}
```

## 2.强制类型转换

```java
1.将取值范围大的数据类型赋值给取值范围小的数据类型
  取值范围小的数据类型 变量名 = 取值范围大的数据类型 -> 需要强转
    
2.怎么强转:
  取值范围小的数据类型 变量名 = (取值范围小的数据类型)取值范围大的数据类型
```

```java
public class Demo10DataType{
    public static void main(String[] args){
        /*
          等号右边的数据是小数,小数默认类型为double
          等号左边的变量是float型
          
          将取值范围大的赋值给取值范围小 -> 报错,需要强转
        */
        //float num1 = 2.5;
        //float num1 = (float)2.5;
        float num1 = 2.5F;
        System.out.println(num1);
        
    }
}
```

## 3.强转的注意事项

```java
1.不要随意写成强转的格式,因为会有精度损失问题以及数据溢出现象,除非没有办法
2.byte,short定义的时候如果等号右边是整数常量,如果不超出byte和short的范围,不需要我们自己强转,jvm自动转型  
    
  byte,short如果等号右边有变量参与,byte和short自动提升为int,然后结果再次赋值给byte或者short的变量,需要我们自己手动强转
    
    
3.char类型数据如果参与运算,会自动提升为int型,如果char类型的字符提升为int型会去ASCII码表(美国标准交换代码)范围内去查询字符对应的int值,如果在ASCII码表范围内没有对应的int值,回去unicode码表(万国码)中找  
```

```java
public class Demo11DataType{
    public static void main(String[] args){
        //精度损失
        int i = (int)2.9;
        System.out.println(i);
        
        /*
          数据溢出
          int型占内存4个字节,4个字节变成二进制是32位
          
          100个亿: 10 0101 0100 0000 1011 1110 0100 0000 0000 -> 34位二进制
          
          100个亿的二进制位比int型的二进制位多出来2位,此时干掉最前面的2位
          
          101 0100 0000 1011 1110 0100 0000 0000
          
          101 0100 0000 1011 1110 0100 0000 0000->1410065408
        */
        int j = (int)10000000000L;
        System.out.println(j);//1410065408
        
        System.out.println("=========================");
        
        byte b = 10;
        System.out.println(b);
        
        b = (byte)(b+1);
        System.out.println(b);
        
        System.out.println("=========================");
        
        char c = '中';
        System.out.println(c+0);//20013
    }
}
```

<img src="img/1698487668942.png" alt="1698487668942" style="zoom:80%;" />

# 第五章.进制的转换(了解)

| 十进制 | 二进制 | 八进制 | 十六进制 |
| ------ | ------ | ------ | -------- |
| 0      | 0      | 0      | 0        |
| 1      | 1      | 1      | 1        |
| 2      | 10     | 2      | 2        |
| 3      | 11     | 3      | 3        |
| 4      | 100    | 4      | 4        |
| 5      | 101    | 5      | 5        |
| 6      | 110    | 6      | 6        |
| 7      | 111    | 7      | 7        |
| 8      | 1000   | 10     | 8        |
| 9      | 1001   | 11     | 9        |
| 10     | 1010   | 12     | a或A     |
| 11     | 1011   | 13     | b或B     |
| 12     | 1100   | 14     | c或C     |
| 13     | 1101   | 15     | d或D     |
| 14     | 1110   | 16     | e或E     |
| 15     | 1111   | 17     | f或F     |
| 16     | 10000  | 20     | 10       |

## 3.1 十进制转成二进制

```java
辗转相除法 -> 循环除以2,取余数
```

<img src="img/1698489992624.png" alt="1698489992624" style="zoom:80%;" />

## 3.2 二进制转成十进制

```java
8421规则
```

<img src="img/1698490196480.png" alt="1698490196480" style="zoom:80%;" />

## 3.3 二进制转成八进制

```java
将二进制数分开  (3位为一组)
```

<img src="img/1698490532286.png" alt="1698490532286" style="zoom:80%;" />

## 3.4 二进制转成十六进制

```java
 将二进制数分组-> 4位为一组
```

<img src="img/1698490908576.png" alt="1698490908576" style="zoom:80%;" />

# 第六章.位运算符(了解)

![1698490638699](img/1698490638699.png)

```java
1.符号的介绍:
  a. &(与) -> 有假则假
  b. |(或) -> 有真则真
  c. ~(非) -> 取反
  d. ^(异或) -> 符号前后结果一样为false,不一样为true
     true ^ true -> false
     false ^ false -> false
     true ^ false -> true
     false ^ true -> true
      
2.   1代表true   0代表false  
      
3.我们要知道计算机在存储数据的时候都是存储的数据的补码,计算也是用的数据的补码 
  但是我们最终看到的结果是原码换算出来的
      
  原码   反码   补码
      
4.正数二进制最高位为0;  负数二进制最高位为1
    
5.如果是正数  原码 反码 补码 一致
  比如:5的原码  反码  补码一致:
      0000 0000 0000 0000 0000 0000 0000 0101 -> 因为是正数,二进制最高位为0
          
  如果是负数,原码 反码 补码不一样了
       反码是原码的基础上最高位不变,剩下的0和1互换
       补码是在反码的基础上+1
          
  比如:-9
       原码: 1000 0000 0000 0000 0000 0000 0000 1001
       反码: 1111 1111 1111 1111 1111 1111 1111 0110
       补码: 1111 1111 1111 1111 1111 1111 1111 0111
```

#### (1)左移:<<

​    **运算规则**:左移几位就相当于乘以2的几次方

​    **注意:**当左移的位数n超过该数据类型的总位数时,相当于左移(n-总位数)位

```java
2<<2   结果等于8
快速算法:  2*(2的2次方)
```

<img src="img/1698492698243.png" alt="1698492698243" style="zoom:80%;" />

```java
-2<<2  等于-8
快速算法: -2*(2的2次方)
```

<img src="img/1698493024906.png" alt="1698493024906" style="zoom:80%;" />

#### (2)右移:>>

快速运算:类似于除以2的n次,如果不能整除,**向下取整**

```java
9>>2  等于2
    
快速算法: 9除以(2的2次方)
```

<img src="img/1698493649466.png" alt="1698493649466" style="zoom:80%;" />

```java
-9>>2   等于-3
    
快速算法: -9除以(2的2次方)
```

<img src="img/1698493979532.png" alt="1698493979532" style="zoom:80%;" />

#### (3)无符号右移:>>>

运算规则:往右移动后,左边空出来的位直接补0,不管最高位是0还是1空出来的都拿0补

正数:和右移一样

```java
9>>>2 等于2
```

负数:右边移出去几位,左边补几个0,结果变为正数

```java
-9>>>2
结果为:1073741821    
```

> 笔试题: 8>>>32位 -> 相当于没有移动还是8
>
> ​              8>>>34位 -> 相当于往右移动2位

#### (4)按位与:&

小技巧:将0看成为false  将1看成true

运算规则:对应位都是1才为1,相当于符号左右两边都为true,结果才为true

1&1 结果为1

1&0 结果为0

0&1 结果为0

0&0 结果为0

```java
5&3 结果1
```

<img src="img/1698494481587.png" alt="1698494481587" style="zoom:80%;" />

#### (5)按位或:|

运算规则:对应位只要有1即为1,相当于符号前后只要有一个为true,结果就是true

1|1    结果1

1|0    结果1

0|1    结果1

0|0    结果0

```
5|3    结果为7
```

<img src="img/1698494610146.png" alt="1698494610146" style="zoom:80%;" />

#### (6)按位异或:^

​    运算规则:对应位一样的为0,不一样的为1

1^1  结果为0  false

1^0  结果为1 true

0^1  结果为1  true

0^0  结果0   false

```java
5^3   结果为6
```

<img src="img/1698494755473.png" alt="1698494755473" style="zoom:80%;" />

#### (7)按位取反

运算规则:~0就是1  

​                   ~1就是0

```java
~10   结果为-11
```

<img src="img/1698494969654.png" alt="1698494969654" style="zoom:80%;" />

# 第七章.运算符的优先级(了解)

<img src="img/1698495032471.png" alt="1698495032471" style="zoom:80%;" />

```java
提示说明:
(1)表达式不要太复杂
(2)先算的使用(),记住,如果想让那个表达式先运行,就加小括号就可以了
i<(n*m)
```
 

# 模块三 idea_运算符

```java
模块二的回顾:
  1.常量:在代码的运行过程中,值不会发生改变的数据
    a.整数常量:所有的整数
    b.小数常量:所有带小数点的  2.0
    c.字符常量:带单引号的,单引号中必须有,且只能有一个内容
    d.字符串常量:带双引号的
    e.布尔常量:true false -> 可以当条件判断使用
    f.空常量:null 代表数据不存在,所以不能直接使用
  2.变量:在代码的运行过程中,会根据不同的情况而随时可以改变的数据
    a.定义:
      数据类型 变量名 = 值 -> 将等号右边的值赋值给等号左边的变量
    b.数据类型:
      基本类型:byte short int long float double boolean char
      引用类型:类 数组 接口 枚举 注解
          
  3.数据类型转换:等号左右两边类型不一致时,或者不同的类型做运算
    a.自动类型转换:小转大
      将取值范围小的类型赋值给取值范围大的类型
      取值范围小的类型和取值范围大的类型之间做运算
    b.强转:大转小
      取值范围小的数据类型 变量名 = (取值范围小的数据类型)取值范围大的数据类型
        
        
模块三的重点:
  all
```

# 第一章.IDEA的使用

## 1.idea的介绍

```java
1.概述:开发工具
2.特点:
  a.idea是java写的,所以本地上必须有正确的jdk环境(JAVA_HOME)
  b.idea自动保存
  c.不用我们打开dos命令窗口执行javac和java命令
  d.idea有强大的快捷键,生成代码,纠错等
  e.idea会自动管理我们写的代码
      
3.相关开发工具:eclipse myeclipse   
    
4.作用:加速我们的开发    
```

<img src="img/1698654549891.png" alt="1698654549891" style="zoom:80%;" />

## 2.idea的目录结构

<img src="img/1698655258798.png" alt="1698655258798" style="zoom:80%;" />

> 先创建project,在project下创建module,在module下创建package -> 必须记住

## 3.Project的操作

### 3.1.project的创建

<img src="img/1698656313192.png" alt="1698656313192" style="zoom:80%;" />

### 3.2再次创建一个新的Project

<img src="img/1698656369654.png" alt="1698656369654" style="zoom:80%;" />

<img src="img/1698656431983.png" alt="1698656431983" style="zoom:80%;" />

<img src="img/1698656486848.png" alt="1698656486848" style="zoom:80%;" />

### 3.3.关闭Project

```java
file-> close project
```

<img src="img/1698656529824.png" alt="1698656529824" style="zoom:80%;" />

### 3.4.打开project

<img src="img/1698656643041.png" alt="1698656643041" style="zoom:80%;" />

## 4.module的操作

### 4.1.创建module

<img src="img/1698657956849.png" alt="1698657956849" style="zoom:80%;" />

<img src="img/1698658056821.png" alt="1698658056821" style="zoom:80%;" />

### 4.2.关闭module

```java
a.对着要关闭的module右键 -> remove module -> 此时是关闭,不是真正的删除module
b.再对着关闭的module右键-> delete -> 从本地上真正删除
```

<img src="img/1698658178382.png" alt="1698658178382" style="zoom:80%;" />

<img src="img/1698658250143.png" alt="1698658250143" style="zoom:80%;" />![1698658413831](img/1698658413831.png)

### 4.3.导入已有的module

<img src="img/1698658424190.png" alt="1698658424190" style="zoom:80%;" />

<img src="img/1698658530931.png" alt="1698658530931" style="zoom:80%;" />

## 5.package的操作

### 5.1创建

<img src="img/1698659767078.png" alt="1698659767078" style="zoom:80%;" />

### 5.2 package的删除

```java
右键-> delete
```

<img src="img/1698659832251.png" alt="1698659832251" style="zoom:80%;" />

### 5.3 package取名字规范

```java
1.公司域名倒着写:
  比如:尚硅谷  域名为:www.atguigu.com
  我们写代码创建包: com.atguigu
```

<img src="img/1698660235926.png" alt="1698660235926" style="zoom:80%;" />

## 6.创建类以及基本语句生成快捷键

<img src="img/1698660395965.png" alt="1698660395965" style="zoom:80%;" />

<img src="img/1698660554481.png" alt="1698660554481" style="zoom:80%;" />

> 1.生成main方法:输入main -> 回车
>
> 2.生成输出语句:sout -> 回车
>
> 3.将变量名放到输出语句中:
>
>    a.变量名.sout
>
>    b.变量名.soutv -> 带字符串平拼接格式的输出方式-> 输出格式好看

## 7.基本设置

### 7.1设置字体

```java
file-settings
```

<img src="img/1698660971384.png" alt="1698660971384" style="zoom:80%;" />

### 7.2设置提示的快捷键

```java
file-settings
```

<img src="img/1698661137410.png" alt="1698661137410" style="zoom:80%;" />![1698661320028](img/1698661320028.png)

### 7.3 设置注释字体

![1698661320028](img/1698661320028.png)

## 8.快捷键

| 快捷键               | 功能                                   |
| -------------------- | -------------------------------------- |
| `Alt+Enter`          | 导入包,自动修正代码(重中之重)         |
| `Ctrl+Y`             | 删除光标所在行                         |
| `Ctrl+D`             | 复制光标所在行的内容,插入光标位置下面 |
| `Ctrl+Alt+L`         | 格式化代码                             |
| `Ctrl+/`             | 单行注释                               |
| `Ctrl+Shift+/`       | 选中代码注释,多行注释,再按取消注释   |
| `Alt+Shift+上下箭头` | 移动当前代码行                         |

> 先写等号右边的,可以自动生成等号左边的变量
>
> <img src="img/1698662119415.png" alt="1698662119415" style="zoom:80%;" />

或者

> <img src="img/1698662152111.png" alt="1698662152111" style="zoom:80%;" />

## 9.出现的问题

```java
1.在运行代码时会出现"找不到对应的发行源"或者"不支持发行版本"或者"无效的发行源版本",证明本地jdk版本和idea中的language level不匹配
  所以要匹配版本
  file->project Structure->点击project->引入本地jdk->project level选择对应的版本
2.没有out路径的问题
  out路径是专门存放idea自动编译生成的.class文件的
  所以需要指明out路径
    
3.src是灰色的,对着src,右键,选项中没有java class或者package
    
4.刚使用,jdk没有配置
```

<img src="img/1698663293553.png" alt="1698663293553" style="zoom:80%;" />

<img src="img/1698663426985.png" alt="1698663426985" style="zoom:80%;" />

# 第二章.运算符

## 1.算数运算符

| 符号 | 说明                                                         |
| ---- | ------------------------------------------------------------ |
| +    | 加法                                                         |
| -    | 减法                                                         |
| *    | 乘法                                                         |
| /    | 除法<br>如果符号前后都是整数,结果取整数部分<br>如果符号前后有一个为小数,结果就是正常小数 |
| %    | 模,取余数部分                                                |

```java
public class Demo01Arithmetic {
    public static void main(String[] args) {
        int i = 10;
        int j = 3;
        int add = i+j;//推荐使用
        System.out.println(add);//13
        System.out.println(i+j);//13

        int sub = i-j;
        System.out.println(sub);//7

        int mul = i*j;
        System.out.println(mul);//30

        int div = i/j;
        System.out.println(div);//3

        int mo = i%j;
        System.out.println(mo);//1
    }
}
```

```java
+:
  1.运算
  2.字符串拼接:任何类型的数据遇到字符串都会变成字符串,此时+就不再是运算了,而是字符串拼接,将内容直接往后拼接    
 
```

```java
public class Demo02Arithmetic {
    public static void main(String[] args) {
        int i = 10;
        int j = 3;
        System.out.println(i+j+"");//13
        System.out.println(i+j+""+1);//131
        System.out.println(i+""+j);//103

        System.out.println("i和j相加只和为:"+(i+j));
    }
}
```

### 1.2.自增自减运算符(也算算数运算符的一种)

```java
1.格式:
  变量++ -> 后自加
  ++变量 -> 前自加
  变量-- -> 后自减
  --变量 -> 前自减
      
  自增和自减只变化1
      
2.使用:
  a.单独使用: ++ -- 单独为一句,没有和其他的语句掺和使用
    i++;

    符号前在在后都是先运算
        
  b.混合使用: ++ -- 和其他的语句掺和使用了(比如:输出语句,赋值语句)
    符号在前:先运算,在使用运算后的值
    符号在后:先使用原值,使用完毕之后,自身再运算
      

public class Demo03Arithmetic {
    public static void main(String[] args) {
        int i = 10;
        //i++;
        ++i;
        System.out.println("i = " + i);

        System.out.println("==================");

        int j = 100;
        int result01 = ++j;
        System.out.println("result01 = " + result01);//101
        System.out.println(j);//101

        System.out.println("==================");
        int k = 10;
        int result02 = k++;
        System.out.println("result02 = " + result02);
        System.out.println(k);

        System.out.println("==================");

        int z = 100;
        System.out.println(z++);
        System.out.println(z);

        System.out.println("==================");

        int x = 10;
        int y = 20;

        /*
           10+19 = 29
           29+12 = 41

           以后开发肯定不会这么写
         */

        int result03 = x++ + --y + ++x;
        System.out.println("result03 = " + result03);

        System.out.println("=======================");

        int c = 10;
        c = c++;
        System.out.println(c);//10
        System.out.println(c);//10

    }
}

## 3.赋值运算符


1.基本赋值运算符

  =  -> 先看等号右边的,再将右边的数据赋值给等号左边的变量

2.复合赋值运算符:

  +=:
    int i = 10;
    i+=2 -> i = i+2
  -=
  *=
  /=  : 取整数部分
  %=  : 取余数部分  

3.注意:byte short 遇到复合赋值运算符,jvm会自动转型      
public class Demo01Assignment {
    public static void main(String[] args) {
        int i = 10;
        i+=2;//i = i+2
        System.out.println(i);
    }
}
public class Demo02Assignment {
    public static void main(String[] args) {
        byte b = 10;
        //b = (byte)(b + 1);
        b+=1;//b = b+1
        //b+=1(不会报错) 不同等于 b=b+1(报错) 
        System.out.println(b);
    }
}
## 4.关系运算符(比较运算符)

1.结果:boolean型 -> 要么是true,要么是false
2.作用:做条件判断使用  

符号说明    
==如果符号前后相等为true;否则为false  
>  如果符号前的数据大于符号后的数据为true,否则为false  
<    如果符号前的数据小于符号后的数据为true,否则为false
>=  如果符号前的数据大于或者等于符号后的数据为true,否则为false
<=如果符号前的数据小于或者等于符号后的数据为true,否则为false
!=  如果符号前后不相等为true;否则为false      
public class Demo01Compare {
    public static void main(String[] args) {
        int i = 10;
        int j = 20;

        boolean result01 = i == j;
        System.out.println("result01 = " + result01);//false
        System.out.println(i>j);//false
        System.out.println(i<j);//true
        System.out.println(i>=j);//false
        System.out.println(i<=j);//true
        System.out.println(i!=j);//true

    }
}
## 5.逻辑运算符

 1.作用:连接多个boolean结果的
 2.结果:boolean型结果    

符号说明    
&&  (与,并且)有假则假,符号前后有一个结果为false,整体就是false    
||     (或者)有真则真,符号前后有一个结果为true,整体就是true    
!      (非,取反)不是true,就是false;不是false,就是true    
^      (异或)

符号前后结果一样为false;不一样为true

true^true -> false

true^false -> true

false^true -> true

false^false -> false

public class Demo01Logic {
    public static void main(String[] args) {
        // 初始化变量
        int i = 10;
        int j = 20;
        int k = 10;

        // && 运算符演示:只有当两个条件都为 true 时,结果才为 true
        boolean result01 = (i > j) && (i == k);
        System.out.println("result01 = " + result01); // false

        // || 运算符演示:只要有一个条件为 true,结果就为 true
        boolean result02 = (i > j) || (i == k);
        System.out.println("result02 = " + result02); // true

        // ^ 运算符演示:异或操作,当两个条件不一致时结果为 true
        boolean result03 = (i > j) ^ (i == k); // false ^ true
        System.out.println("result03 = " + result03); // true

        // ! 运算符演示:对条件取反
        boolean result04 = !(i > j);
        System.out.println("result04 = " + result04); // true
    }
}
符号说明        
&

1.单与,如果前后都是布尔型,有假则假,但是如果符号前为false,符号后的判断会继续执行。

2.如果该符号前后都是数字,看做是位运算符

&&  1.双与,有假则假,但是有短路效果,如果符号前为false,符号后的判断就不会执行了
|

1.单或,如果前后都是布尔型,有真则真,但是如果符号前为true,符号后的判断会继续执行

2.如果该符号前后都是数字,看做是位运算符

||1.双或,有真则真,但是有短路效果,如果符号前为true,符号后的判断就不会执行了
public class Demo02Logic {

    public static void main(String[] args) {
/**
 * 此代码段演示了如何使用逻辑运算符对两个整数进行条件判断。
 * 该程序首先初始化两个整数a和b,然后使用逻辑运算符对它们进行比较,
 * 并根据比较结果输出相关信息。
 * 该代码段特别演示了逻辑运算符的用法,以及如何在条件判断中使用递增运算符。
 */
//        boolean result01 = (++a>100)&(++b>10);
//        boolean result01 = (++a > 100) && (++b > 10);
//        boolean result01 = (++a<100)|(++b>10);
        int a = 10; // 初始化变量a为10
        int b = 20; // 初始化变量b为20

// 判断递增后的a是否小于100,或者递增后的b是否大于10,并将结果赋值给result01
        boolean result01 = (++a < 100) || (++b > 10);
        System.out.println("result01 = " + result01); // 输出result01的值

        System.out.println("a = " + a); // 输出a的最终值
        System.out.println("b = " + b); // 输出b的最终值
    }
}

问题:定义一个变量(a),随意给一个值,判断这个变量接收的值是否在1-100之间
        1<=a<=100                (错误,这是数学写法)
         i>=1 && i<=100         (java写法,用逻辑运算符拼接多个判断)

## 6.三元运算符

1.格式:
  boolean表达式?表达式1:表达式2
2.执行流程:
  先判断,如果是true,就走?后面的表达式1,否则就走:后面的表达式2

### 6.1练习1(需求):小明考完试了,判断小明的分数是否及格,返回结果
/**
 * 本类演示了三元操作符的使用。
 */
public class Demo01Ternary {
    /**
     * 主函数。
     * @param args 命令行参数。
     */
    public static void main(String[] args) {
        // 定义变量score,表示小明的考试分数
        int score = 60;
        // 使用三元操作符根据score的值决定result的值
        String result = score >= 60 ? "及格" : "不及格";
        // 打印结果
        System.out.println("result = " + result);
    }
}
### 6.2练习2:有两个老人,年龄分别为70  80  求出两个老人的最高年龄
 
/**
 * 测试三元运算符的用例。
 * 该程序不接受任何参数,也无返回值。
 */
public class Demo02Ternary {
    public static void main(String[] args) {
        // 初始化两个整数变量
        int old1 = 70;
        int old2 = 80;
        
        // 使用三元运算符找出两个数中较大的一个
        int max = old1 > old2 ? old1 : old2;
        // 打印最大值
        System.out.println("max = " + max);


//        int a = 70;
//        int b = 80;
//
//        // 直接使用三元运算符实现的 max 方法比较 a 和 b 的大小
//        String c = (a > b) ? "a is greater than b." :
//                (a < b) ? "b is greater than a." :
//                        "a and b are equal.";
//
//        System.out.println(c);


    }
}
### 6.3 练习3:有三个老人,年龄分别为70  80  60  求出三个老人的最高年龄
/**
 * 计算三位老人年龄的最大值。
 */
public class Demo03Ternary {
    public static void main(String[] args) {

        // 定义三位老人的年龄
        int age1 = 70;
        int age2 = 80;
        int age3 = 60;

        // 使用三元运算符计算并存储最大年龄
        int maxAge = (age1 > age2) ? ((age1 > age3) ? age1 : age3) : ((age2 > age3) ? age2 : age3);

        // 输出最高年龄
        System.out.println("The highest age among the three elders is: " + maxAge);

//方法2
//        // 初始化三个整数
//        int old1 = 70;
//        int old2 = 80;
//        int old3 = 60;
//
//        // 使用三元运算符找到old1和old2中的较大值,并将其赋给temp变量
//        int temp = old1 > old2 ? old1 : old2;
//
//        // 再次使用三元运算符找到temp和old3中的较大值,并将其赋给max变量
//        int max = temp > old3 ? temp : old3;
//
//        // 输出最大值
//        System.out.println("max = " + max);

    }
}

day4# 模块四_流程控制

```java
模块三重点回顾:
  1.idea -> 自己看
  2.算数运算符: + - * / %(取余数)
    +:字符串拼接 -> 内容直接往后拼接
        
    自增自减:++ --
        a.单独使用:符号在前在后都是先运算
        b.混合使用:符号在前先运算,再使用运算后的值
                  符号在后先使用原值,再运算
            
  3.赋值运算符:
    = += -= *= /= %=
  4.比较运算符:结果都是boolean型的
    == > < >= <= !=    
      
  5.逻辑运算符:连接boolean结果的,结果还是boolean
    &&(短路效果) ||(短路效果) !(取反)  ^
      
  6.三元运算符:
    a.格式:
      boolean表达式?表达式1:表达式2
    b.执行流程:先走boolean表达式,如果是true,就走?后面的表达式1,否则就走:后面的表达式2


模块四重点:

  1.会使用Scanner和Random
  2.会使用switch以及知道case的穿透性
  3.会使用if
  4.会使用for循环,while循环,嵌套循环
  
```

# 第一章.键盘录入_Scanner

1.概述:是java定义好的一个类
2.作用:将数据通过键盘录入的形式放到代码中参与运行 
3.位置:java.util
4.使用:
  a.导包:通过导包找到要使用的类 -> 导包位置:类上
    import java.util.Scanner -> 导入的是哪个包下的哪个类
      
  b.创建对象
    Scanner 变量名 = new Scanner(System.in);

  c.调用方法,实现键盘录入
    变量名.nextInt() 输入整数int型的
    变量名.next() 输入字符串  String型的  

/**
 * Demo01Scanner类:演示如何使用Scanner类从标准输入读取数据。
 */
public class Demo01Scanner {
    /**
     * main方法:程序的入口点。
     * @param args 命令行参数,本程序未使用该参数。
     */
    public static void main(String[] args) {
        // 创建一个Scanner对象,用于从System.in读取输入
        Scanner sc = new Scanner(System.in);

        // 读取一个整数,并打印出来
        int datal = sc.nextInt();
        System.out.println("daral=" + datal);

        // 读取一个字符串,并打印出来
        String data2 = sc.next();
        System.out.println("data2" + data2);

    }
}

====================================================

public class Demo02Scanner {
        /**
         * main方法:程序的入口点。
         * @param args 命令行参数(未使用)
         */
        public static void main(String[] args) {
            // 创建Scanner对象,用于从System.in读取输入
            Scanner sc = new Scanner(System.in);

            // 录入三个int型整数
            int old1 = sc.nextInt();
            int old2 = sc.nextInt();
            int old3 = sc.nextInt();

            // 通过两次比较找出三个数中的最大值
//            int max = (old1 > old2) ? ((old1 > old3) ? old1 : old3) : ((old2 > old3) ? old2 : old3);
            int temp = old1 > old2 ? old1 : old2; // 首先比较old1和old2,较大的赋值给temp
            int max = temp > old3 ? temp : old3; // 再比较temp和old3,较大的赋值给max
            System.out.println(max); // 输出最大值

        }
}

变量名.next():        录入字符串 -> 遇到空格和回车就结束录入了
变量名.nextLine(): 录入字符串 -> 遇到回车就结束录入了

一起用需要在nextLine()前额外调用一次nextLine()来“消费”掉因next()遗留的换行符,确保后续nextLine()能正确读取用户的下一行输入

package com.atguigu.helloworld;

import java.util.Scanner;

/**
 * Demo01Scanner类:演示如何使用Scanner类从标准输入读取数据。
 * 本类不接受任何参数,也不返回任何值。
 */
public class Demo01Scanner {

        /**
         * main方法:程序的入口点。
         * @param args 命令行参数数组,本示例中未使用。
         */
        public static void main(String[] args) {
            // 创建一个Scanner对象,用于从System.in读取输入
            Scanner sc = new Scanner(System.in);
            // 读取下一个整数或单词
            String data1 = sc.next();
            // 读取下一行的文本
            String data2 = sc.nextLine();
            // 打印读取的数据
            System.out.println(data1);
            System.out.println(data2);


        }
}



//HHHH   GGGG  
//HHHH
//        GGGG
//一起用会从第一次结束

当next()和nextLine()一起使用时可能产生的问题:
问题1:跳过下一行输入
如果先调用next()读取了一个单词或整数后,紧接着调用nextLine(),此时nextLine()可能会直接跳过用户的下一行输入,而读取到一个空字符串,原因在于:
next()在读取完一个单词或整数后,遇到了分隔符(如空格或换行符),它会停止读取并丢弃这个分隔符。
此时,输入流的当前位置正好位于该分隔符之后,即已经处于下一行的开始位置。
接着调用nextLine()时,由于其以换行符作为分隔符,所以它立即找到了当前行末尾的换行符,从而导致没有等待用户新输入就直接返回一个空字符串。

// 用户输入:Hello world (按回车)
String word = scanner.next(); // word = "Hello"
String line = scanner.nextLine(); // line = "" (因为直接读取了上一行末尾的换行符)

// 用户未能在此处输入新的文本就被跳过

解决办法:
在next()与nextLine()交替使用时,通常需要在nextLine()前额外调用一次nextLine()来“消费”掉因next()遗留的换行符,确保后续nextLine()能正确读取用户的下一行输入:

// 用户输入:Hello world (按回车)
String word = scanner.next(); // word = "Hello"
scanner.nextLine(); // 忽略此处的空行
String line = scanner.nextLine(); // 正确等待用户输入新的一行

// 用户可以在此处输入新的文本

问题2:数据类型匹配不当
next()常用于读取特定类型的数据,如整数(nextInt())、浮点数(nextFloat())等。若用户输入的数据不符合预期类型,会导致InputMismatchException异常。
而nextLine()通常用于读取一整行文本,无论其中包含何种字符。因此,不应混用next()系列方法和nextLine()来读取同一类型的数据,避免引发类型匹配错误或数据丢失。
综上所述,在使用Scanner的next()和nextLine()方法时,应清楚理解它们的区别,并注意避免以上提到的问题。根据实际需求选择合适的方法,保持逻辑清晰,确保正确地读取用户输入。

 Exception in thread "main" java.util.InputMismatchException -> 输入类型不匹配异常
     at java.base/java.util.Scanner.throwFor(Scanner.java:939)
     at java.base/java.util.Scanner.next(Scanner.java:1594)
     at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
     at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
     at com.atguigu.a_scanner.Demo04Scanner.main(Demo04Scanner.java:8)
     
 原因:录入的数据和要求的数据类型不一致    

# 第二章.Random随机数

学习Random和学习Scanner方式方法一样
        1.概述:java自带的一个类
        2.作用:可以在指定的范围内随机一个整数
        3.位置:java.util
        4.使用:
                a.导包:import java.util.Random
                b.创建对象:Random 变量名 = new Random()
                c.调用方法,生成随机数:变量名.nextInt() ->在int的取值范围内随机一个整数

package com.atguigu.helloworld;

import java.util.Random;

/**
 * Demo01Random类用于演示如何使用java.util.Random生成随机数。
 */
public class Demo01Random {
    
    /**
     * main方法是程序的入口点。
     * @param args 命令行参数,本程序未使用该参数。
     */
    public static void main(String[] args) {
        // 创建Random对象,用于生成随机数
        Random rd = new Random();
        // 生成一个范围在[-2^31, 2^31-1]内的随机整数
        int data = rd.nextInt();
        // 打印生成的随机数
        System.out.println(data);
    }
}

在指定范围内随机一个数:nextInt(int bound) ——>在0-(bound-1)
        a.nextInt(10) —— 0-9
        b.在1-10之间随机一个数:        nextInt(10)+1——  (0-9)+1 ——— 1-10
        c.在1-100之间随机一个数:      nextInt(100)+1——(0-99)+1———1-100
        d.在100-999之间随机一个数:  nextInt(900)+100—(0-899)+100 —100-999

package com.atguigu.helloworld;

import java.util.Random;

/**
 * Demo01Random类用于演示如何使用java.util.Random生成随机数。
 */
public class Demo01Random {
    /**
     * 主函数:演示如何使用Random类生成随机数。
     * 参数:args - 传入的命令行参数数组。
     * 返回值:无。
     */
    public static void main(String[] args) {
        // 创建Random对象以生成随机数
        Random rd = new Random();
        // 生成一个范围在[1, 100]内的随机整数
        int data1 = rd.nextInt(100) + 1;
        // 打印生成的随机数
        System.out.println(data1);
        // 生成一个范围在[100, 1000]内的随机整数
        int data2 = rd.nextInt(1000) + 100;
        System.out.println(data2);
    }
}

# 第三章.switch(选择语句)

学switch  if  循环必须要先掌握定义格式,然后掌握执行流程(带一个数进去,根据执行流程观察值的变化)

## 1.switch基本使用

1.格式:

  switch(变量){
      case 常量值1:
          执行语句1;
          break;
          
      case 常量值2:
          执行语句2;
          break;
          
      case 常量值3:
          执行语句3;
          break;
          
      case 常量值4:
          执行语句4;
          break;
          ...
      default:
          执行语句n;
          break;
  }

2.执行流程:用变量接收的值和下面case后面的常量值匹配,匹配上哪个case就执行哪个case对应的执行语句,如果以上所有case都没有匹配上,就走default对应的执行语句n
3.break关键字:代表的是结束switch语句                                                                                          4.default子句是可选的,用于指定当switch表达式的值与所有case子句都不匹配时应执行的代码。通常放在switch结构的最后,但也可以根据需要放在任何位置。
5.注意:switch能匹配什么类型的数据:byte short int char 枚举类型 String类型

switch语句中的case子句和default子句之间不允许有其他语句(除了空语句)。

/**
 * Demo01Switch类用于展示使用switch语句根据输入的整数打印不同的诗句。
 */
public class Demo01Switch {
    /**
     * main方法是程序的入口点。
     * @param args 命令行参数数组。
     */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in); // 创建Scanner对象用于从System.in读取输入
        System.out.println("请您输入一个整数:"); // 提示用户输入一个整数
        int data = sc.nextInt(); // 读取用户输入的整数
        // 使用switch语句根据输入的整数选择不同的执行路径
        switch (data){
            case 1:
                System.out.println("鹅鹅鹅"); // 如果输入为1,打印鹅鹅鹅
                break;
            case 2:
                System.out.println("曲项向天歌"); // 如果输入为2,打印曲项向天歌
                break;
            case 3:
                System.out.println("白毛浮绿水"); // 如果输入为3,打印白毛浮绿水
                break;
            case 4:
                System.out.println("红掌拨清波"); // 如果输入为4,打印红掌拨清波
                break;
            default:
                System.out.println("下面没有了"); // 如果输入不是1-4中的任意一个数字,打印下面没有了
                break;
        }
    }
}
  System.out.println("鹅鹅鹅"); // 如果输入为1,打印鹅鹅
## 2.case的穿透性

1.如果没有break,就会出现case的穿透性,程序就一直往下穿透执行,直到遇到了break或者switch或者代码执行完毕了,就停止了

/**
 * Demo02Switch类用于展示使用switch语句根据输入的数字打印相应的诗句。
 */
public class Demo02Switch {
    /**
     * main方法是程序的入口点。
     * @param args 命令行参数(未使用)
     */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in); // 创建Scanner对象用于从控制台读取输入
        int data = sc.nextInt(); // 读取一个整数作为switch语句的条件
        switch (data){
            case 1:
                System.out.println("鹅鹅鹅");
            case 2:
                System.out.println("曲项向天歌");
            case 3:
                System.out.println("白毛浮绿水");
            case 4:
                System.out.println("红掌拨清波");
                break; // 结束switch语句的执行
            default:
                System.out.println("下面没有了");
                break; // 如果输入的数字不是1到4,打印提示信息并结束switch语句的执行
        }
    }
}

/**
 * 根据输入的月份判断季节。
 * 该程序会从标准输入读取一个整数,代表月份,然后根据月份打印出对应的季节。
 * 
 * @param args 不需要传入参数
 */
public class Demo03Switch {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);  // 创建Scanner对象,用于从控制台读取输入
        int month = sc.nextInt();   // 读取一个整数,代表月份

        // 使用switch语句根据月份判断季节
        switch(month){
            case 12:
            case 1:
            case 2: // 这几个月为冬季
                System.out.println("冬季");
                break;
            case 3:
            case 4:
            case 5: // 这几个月为春季
                System.out.println("春季");
                break;
            case 6:
            case 7:
            case 8: // 这几个月为夏季
                System.out.println("夏季");
                break;
            case 9:
            case 10:
            case 11: // 这几个月为秋季
                System.out.println("秋季");
                break;
            default: // 处理非法输入的情况
                System.out.println("什么情况,你家有这个月份?");
        }
    }
}

# 第四章.分支语句

### 1.if的第一种格式

1.格式:

  if(boolean表达式){
      执行语句;
  }

2.执行流程:
         先走if后面的boolean表达式,如果是true,就走if后面大括号中的执行语句,否则就不走
3.注意:
         if后面跟的是boolean表达式,只要是结果为boolean型的,都可以放在小括号中,哪怕直接写一个true或者false。

/**
 * Demo01If类用于演示简单的if条件语句。
 * 该程序接收两个整数输入,并检查它们是否相等。
 * 不返回任何值。
 */
public class Demo01If {
    public static void main(String[] args) {
        // 创建Scanner对象用于从标准输入读取数据
        Scanner sc = new Scanner(System.in);
        // 读取第一个整数输入
        int data1 = sc.nextInt();
        // 读取第二个整数输入
        int data2 = sc.nextInt();
        // 使用if语句判断两个整数是否相等
        if (data1==data2){
            // 如果相等,打印输出信息
            System.out.println("两个整数相等");
        }
    }
}
### 2.if的第二种格式

1.格式:

  if(boolean表达式){
      执行语句1;
  }else{
      执行语句2;
  }

2.执行流程:
  a.先走if后面的boolean表达式,如果是true,就走if后面的执行语句1
  b.否则就走else后面的执行语句2    

/**
 * Demo02IfElse类,用于演示基于用户输入的两个整数的比较。
 */
public class Demo02IfElse {
    /**
     * main方法,程序的入口点。
     * @param args 命令行参数,本程序未使用该参数。
     */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in); // 创建Scanner对象,用于从控制台读取输入
        int data1 = sc.nextInt(); // 读取第一个整数
        int data2 = sc.nextInt(); // 读取第二个整数
        // 比较两个整数是否相等
        if (data1==data2){
            System.out.println("两个整数相等");
        }else{
            System.out.println("两个整数不相等");
        }
    }
}


 

#### 2.1 练习
任意给出一个整数,请用程序实现判断该正整数是奇数还是偶数,并在控制台输出该整数是奇数还是偶数
package com.atguigu.helloworld;
import javax.swing.*;
import java.util.Scanner;
public class Demo03IfElse {
    public static  void main(String [] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请任意输入一个正整数");
        int a = sc.nextInt();
        if (a%2==0 && a>0) {
            System.out.println("偶数");
        }else if (a%2!=0 && a > 0){
            System.out.println("奇数");
        }
        else if (a<=0){
            System.out.println("输入错误");
        }
        System.out.println(a);
    }
}
#### 2.2练习
需求.利用if  else 求出两个数的较大值
package com.atguigu.helloworld;
import javax.swing.*;
import java.util.Scanner;
public class Demo04IfElse {
    public static  void main(String [] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请任意输入");
        int a = sc.nextInt();
        int b = sc.nextInt();
        if(a>b) {
            System.out.println("a>b=" + b);
        }else{
            System.out.println("b>a=" + a);
        }

    }
}

package com.atguigu.helloworld;
import javax.swing.*;
import java.util.Scanner;
public class Demo05IfElse {
    public static  void main(String [] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("请输入三个整数:");
        int num1 = scanner.nextInt();
        int num2 = scanner.nextInt();
        int num3 = scanner.nextInt();

        int maxNum; // 用于存储三者中的最大值

        // 使用 if-else 结构比较并找出最大值
        if (num1 >= num2 && num1 >= num3) {
            maxNum = num1;
        } else if (num2 >= num1 && num2 >= num3) {
            maxNum = num2;
        } else {
            maxNum = num3;
        }

        System.out.println("三个数中的最大值是: " + maxNum);

        scanner.close();
    }
}
#### 2.3练习
案例:从键盘输入年份,请输出该年的2月份的总天数。闰年2月份29天,平年28天。
闰年:
 a.能被4整除,但是不能被100整除  year%4==0 && year%100!=0
 b.或者能直接被400整除  year%400==0

步骤:
  1.创建Scanner对象,调用nextInt键盘录入一个年份 year
  2.判断(year%4==0 && year%100!=0) || (year%400==0)
  3.如果条件成立,就输出闰年2月29天,否则输出平年2月28天    

package com.atguigu.helloworld;

import javax.swing.*;
import java.util.Scanner;

/**
 * 判断输入的年份是否为闰年
 * @param args 命令行参数
 */
public class Demo06IfElse {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);  // 创建Scanner对象,用于从控制台接收输入

        System.out.println("请输入年份:");  // 提示用户输入年份
        int year = scanner.nextInt();  // 读取用户输入的年份

        // 判断年份是否为闰年
        if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
            System.out.println(year + "是闰年");  // 如果是闰年,输出相应信息
        } else {
            System.out.println(year + "不是闰年");  // 如果不是闰年,输出相应信息
        }
    }
}
#### 2.4练习:输出i的值
public class Demo07IfElse {
    public static void main(String[] args) {
        boolean num1 = false;
        boolean num2 = true;

        int i = 1;

        /*
           num1 = false
           num2 = true
           num1 = num2 -> 相当于将num2的true赋值给了num1
         */
        if (num1=num2){
            i++;
            System.out.println(i);//2
        }

        if (false){
            --i;
            System.out.println(i);
        }
    }
}

//2
### 3.if的第三种格式

1.格式:

  if(boolean表达式){
      执行语句1
  }else if(boolean表达式){
      执行语句2
  }else if(boolean表达式){
      执行语句3
  }...else{
      执行语句n
  }

2.执行流程:
从if开始往下挨个判断,哪个if判断结果为true,就走哪个if对应的执行语句,如果以上所有的判断都是false,就走else对应的执行语句n
      
3.使用场景:2种情况以上的判断      

    /**
     * Demo08ElseIf类展示了使用else if和else来处理多种条件判断的示例。
     * 该类没有构造方法和成员变量,主要通过静态方法main执行。
     *
     * @param args 命令行参数(未使用)
     */
    public class Demo08ElseIf {
        /**
         * 主方法,用于演示else if的使用。
         * 首先从标准输入读取两个整数,然后比较它们的大小,并输出相应的结果。
         *
         * @param args 命令行参数(未使用)
         */
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in); // 创建Scanner对象用于从System.in读取输入
            int data1 = sc.nextInt(); // 读取第一个整数
            int data2 = sc.nextInt(); // 读取第二个整数

            // 使用else if和else结构来判断data1与data2的关系并输出结果
            if (data1 > data2) {
                System.out.println("data1大于data2");
            } else if (data1 < data2) {
                System.out.println("data1小于data2");
            } else if (data1 == data2) {
                System.out.println("data1等于data2");
            }
        }
    }

注意:最后一种情况,不一定非得用else,但是必须要保证所有的情况都判断了

#### 3.1.练习

需求:
 键盘录入一个星期数(1,2,...7),输出对应的星期一,星期二,...星期日

输入  1      输出    星期一
输入  2      输出    星期二
输入  3      输出    星期三
输入  4      输出    星期四
输入  5      输出    星期五
输入  6      输出    星期六
输入  7      输出    星期日
输入  其它数字   输出      数字有误

```java
public class Demo09ElseIf {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int week = sc.nextInt();

//    /**
//     * 根据输入的星期几数值,输出对应的星期名称。
//     * @param week 表示星期几的数字,1表示周一,2表示周二,以此类推,7表示周日。
//     * @return 该函数没有返回值。
//     */
//    public class Main {
//        public static void main(String[] args) {
//            int week = 3; // 假设当前是周三
//            // 根据week的值,输出对应的星期名称
//            if (week==1){
//                System.out.println("周一");
//            }else if (week==2){
//                System.out.println("周二");
//            }else if (week==3){
//                System.out.println("周三");
//            }else if (week==4){
//                System.out.println("周四");
//            }else if (week==5){
//                System.out.println("周五");
//            }else if (week==6){
//                System.out.println("周六");
//            }else if (week==7){
//                System.out.println("周日");
//            }else{
//                // 如果输入的week值不在1到7之间,则输出错误信息
//                System.out.println("是不是有点大病,没有这个星期!");
//            }
//        }
//    }


        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);  // 创建 Scanner 对象用于读取用户输入
            int week = sc.nextInt();   // 读取用户输入的星期序号

            /* 使用注释掉的代码块和 if-else if 结构来判断并输出对应的星期几。这种方式较为繁琐。*/

            // 优化后的代码使用嵌套的 if-else 结构,先判断输入是否在有效范围内,再根据具体值输出对应的星期几
            if (week<1 || week>7){
                System.out.println("是不是有点大病,没有这个星期!");  // 对输入范围外的值给出错误提示
            }else{
                // 根据输入的序号输出对应的星期几
                if (week==1){
                    System.out.println("周一");
                }else if (week==2){
                    System.out.println("周二");
                }else if (week==3){
                    System.out.println("周三");
                }else if (week==4){
                    System.out.println("周四");
                }else if (week==5){
                    System.out.println("周五");
                }else if (week==6){
                    System.out.println("周六");
                }else if (week==7){
                    System.out.println("周日");
                }
            }
        }
    }
#### 3.2练习

根据最新的年龄段划分标准:
  0-6岁为婴幼儿
  7-12岁为少儿
  13-17岁为青少年
  18-45岁为青年
  46-69岁为中年
  69岁以上为老年
请键盘录入一个年龄,判断属于什么年龄段  

/**
 * 根据输入的年龄判断其对应的人生阶段。
 * 该程序首先接收用户输入的年龄,然后通过一系列的if-else if结构判断年龄所属的阶段,
 * 并输出相应的结果。最后,对年龄进行一次合法性检查,确保年龄在合理的范围内。
 */
public class Demo10ElseIf {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in); // 创建Scanner对象,用于接收用户输入
        int age = sc.nextInt(); // 读取用户输入的年龄

//        if (age>=0 && age<=6){
//            System.out.println("婴幼儿");
//        }else if (age>=7 && age<=12){
//            System.out.println("少儿");
//        }else if (age>=13 && age<=17){
//            System.out.println("青少年");
//        }else if(age>=18 && age<=45){
//            System.out.println("青年");
//        }else if(age>=46 && age<=69){
//            System.out.println("中年");
//        }else if (age>69 && age<=130){
//            System.out.println("老年");
//        }else {
//            System.out.println("年龄不太符合实际");
//        }

        if (age<0 || age>130){
            System.out.println("年龄不太符合实际");
        }else{
            // 根据年龄输出对应的人生阶段
            if (age>=0 && age<=6){
                System.out.println("婴幼儿");
            }else if (age>=7 && age<=12){
                System.out.println("少儿");
            }else if (age>=13 && age<=17){
                System.out.println("青少年");
            }else if(age>=18 && age<=45){
                System.out.println("青年");
            }else if(age>=46 && age<=69){
                System.out.println("中年");
            }else if (age>69 && age<=130){
                System.out.println("老年");
            }
        }
    }
}

switch和if的区别:debug
        1.switch:会直接跳到相匹配的case
        2.if:从上到下挨个判断 -> 实际开发主要用if做判断,灵活  

# 第五章.循环语句

什么时候使用循环语句:
  当我们发现一件事或者一段代码在反复执行,我们就可以考虑使用循环语句了

## 1.for循环

1.格式:

  for(初始化变量;比较;步进表达式){
      循环语句 -> 哪段代码循环执行,就将哪段代码放到此处
  }

2.执行流程:
  a.先走初始化变量
  b.比较,如果是true,走循环语句,走步进表达式(初始化的变量的值进行变化) 
  c.再比较,如果还是true,继续走循环语句,走步进表达式
  d.再比较,直到比较为false,循环结束了

public class Demo01For {
    /**
     * main方法是程序的入口点。
     * @param args 命令行参数数组,本示例中未使用。
     */
    public static void main(String[] args) {
        // 使用for循环打印三次"我爱java"
        for(int i = 0;i<3;i++){
            System.out.println("我爱java");
        }
    }
}

 快捷键: 次数.fori

### 1.1练习


for循环:求1-3之间的数据和,并把求和结果输出到控制台上
1+2+3
    
步骤:
  1.定义一个变量,用来接受两个数的和  sum
  2.利用for循环将1-100表示出来
  3.在循环的过程中,两两相加,将结果赋值给sum
  4.输出sum    

public class Demo02For {

    public static void main(String[] args) {
        int sum = 0;
        for (int i = 1;  i <= 100; i++)
        {
            sum = sum + i;
        }
        System.out.println("1到100的和为:" + sum);
    }
}
### 1.2练习

```java
需求:求出1-100的偶数和步骤:
  1.定义一个变量sum,接受两个偶数的和
  2.利用for循环将1-100表示出来
  3.判断,如果是偶数,相加,将加的结果赋值给sum
  4.输出sum    

public class Demo02For {

    public static void main(String[] args) {
        int sum = 0;
        for (int i = 1;  i <= 100; i++)
        {
            if(i % 2 == 0) {
                sum += i;
            }
        }
        System.out.println("1到100的偶数和为:" + sum);
    }
}
### 1.3练习

统计一下1-100之间的偶数个数步骤:
  1.定义一个变量count,用来计数
  2.利用for循环将1-100表示出来
  3.判断,如果是偶数,count++
  4.输出count    

ublic class Demo02For {

    public static void main(String[] args) {
        int count = 0;
        for (int i = 1;  i <= 100; i++)
        {
            if(i % 2 == 0) {
                count++;//count += 1;
            }
        }
        System.out.println("1到100的偶数个数为:" + count);
    }
}
## 2.while循环

1.格式:

  初始化变量;
  while(比较){
      循环语句;
      步进表达式
  }

2.执行流程:
  a.初始化变量
  b.比较,如果是true,就走循环语句,走步进表达式
  c.再比较,如果还是true,继续走循环语句,继续走步进表达式
  d.再比较,直到比较为false,循环结束

public class Demo01While {
    /**
     * main方法,程序的入口点。
     * @param args 命令行参数,此处未使用。
     */
    public static void main(String[] args) {
        int i = 0; // 初始化计数器i为0
        // 当i小于5时,循环执行打印操作
        while(i<5){
            System.out.println("我爱java,我更爱钱"); // 打印指定字符串
            i++; // 计数器递增
        }
    }
}
/**
 * Demo02While类,主要演示了while循环的基本使用。
 */
public class Demo02While {
    /**
     * main方法,程序的入口点。
     * @param args 命令行参数,此处未使用。
     */
    public static void main(String[] args) {
        // 初始化总和为0和计数器i为1
        int sum = 0;
        int i = 1;
        
        // 当i小于等于3时,循环执行累加操作
        while(i<=3){
            sum+=i; // 将i加到sum上
            i++; // i自增1
        }
        
        // 输出累加结果
        System.out.println("sum = " + sum);
    }
}
/**
 * Demo03While类主要演示了使用while循环计算1到100之间所有偶数的和。
 */
public class Demo03While {
    /**
     * main方法是程序的入口点。
     * @param args 命令行参数数组。
     */
    public static void main(String[] args) {
        int sum = 0; // 初始化总和为0
        int i = 1; // 从1开始遍历
        
        // 当i小于等于100时,持续循环
        while (i <= 100) {
            // 如果i是偶数,将其加到总和上
            if (i % 2 == 0) {
                sum += i;
            }
            i++; // i递增
        }
        
        // 打印计算得到的总和
        System.out.println("sum = " + sum);
    }
}
/**
 * Demo04While类主要演示了使用while循环统计从1到100中偶数的个数。
 * 该程序没有参数,也没有返回值。
 */
public class Demo04While {
    /**
     * main方法是程序的入口点。
     * @param args 命令行参数,本程序未使用。
     */
    public static void main(String[] args) {
        // 初始化计数器和起始数值
        int count = 0;
        int i = 1;
        
        // 循环遍历1到100之间的所有数字
        while (i <= 100) {
            // 如果当前数字是偶数,则计数器加一
            if (i % 2 == 0) {
                count++;
            }
            // 数字加一,准备下一次循环
            i++;
        }
        
        // 打印统计结果
        System.out.println("count = " + count);
    }
}

### 1.1while练习


需求:世界最高山峰是珠穆朗玛峰(8844.43米=8844430毫米),假如我有一张足够大的纸,它的厚度是0.1毫米。请问,我折叠多少次,可以折成珠穆朗玛峰的高度? 27步骤:
  1.定义一个变量表示山峰的高度  mountain
  2.定义一个变量表示纸的厚度    paper
  3.定义一个变量表示折纸的次数  count
  4.利用while循环循环比较,如果paper<mountain 就循环对折
    paper = paper*2;
    count++;
  5.输出count

/**
 * 此类演示了通过不断对折纸张来达到与山峰高度相比较的示例。
 * 通过while循环来判断纸的厚度是否小于山峰的高度,如果小于,则进行对折,直到纸的厚度大于或等于山峰的高度。
 * 最后输出折纸的次数。
 */
public class Demo05While {
    public static void main(String[] args) {
        // 定义初始山峰的高度
        int mountain = 8844430;
        // 定义初始纸的厚度
        double paper = 0.1;
        // 定义折纸次数
        int count = 0;
        
        // 当纸的厚度小于山峰的高度时,进行循环对折
        while(paper < mountain) {
            paper *= 2; // 对折纸张
            count++; // 折纸次数增加
        }
        
        // 输出折纸的次数
        System.out.println("count = " + count);
    }
}
## 3.do...while循环(了解)

1.格式:

 初始化变量;
  do{
      循环语句;
      步进表达式
  }while(比较);

2.执行流程:
  a.初始化变量
  b.走循环语句
  c.走步进表达式
  d.判断,如果是true,继续循环,直到比较为false,循环结束
      
3.特点:
  至少循环一次

/**
 * Demo01DoWhile类,演示了do-while循环的基本用法。
 */
public class Demo01DoWhile {
    /**
     * main方法,程序的入口点。
     * @param args 命令行参数,此处未使用。
     */
    public static void main(String[] args) {
        // 初始化计数器i为0
        int i = 0;
        // 进入循环,先执行循环体内的操作,然后判断条件
        do{
            System.out.println("我爱java"); // 输出指定字符串
            i++; // 计数器递增
        }while(i<5); // 当i小于5时,继续循环
    }
}
## 4.循环控制关键字

1.break:
  a.在switch中代表结束switch语句
  b.在循环中代表结束循环 
      
2.continue:
  结束当前本次循环,直接进入下一次循环,直到条件为false为止

/**
 * Demo01BreakAndContinue类,演示了break和continue在循环中的使用。
 */
public class Demo01BreakAndContinue {
    /**
     * main方法,程序的入口点。
     * @param args 命令行参数数组。
     */
    public static void main(String[] args) {
        // for循环,从1遍历到5
        for (int i = 1; i <= 5; i++) {
            // 当i等于3时,执行continue,跳过当前循环的剩余部分
            if (i==3){
                // 此处的break被注释掉了,如果取消注释,将会在i等于3时终止整个循环
                // continue; 
            }
            // 输出"我爱java"加上当前的循环次数i
            System.out.println("我爱java"+i);
        }
    }
}
## 5.死循环

1.概述:
  一直循环
2.什么条件下一直循环:
  比较条件一直是true

/**
 * 本类用于演示一个简单的无限循环的实现方式。
 */
public class Demo01Endless {
    /**
     * 主函数入口。
     * @param args 命令行参数数组。
     */
    public static void main(String[] args) {
        int count = 0; // 初始化计数器
        // 使用for循环实现一个简单的无限循环,打印计数器累加的值。
        for (int i = 0; i < 10;) {
            count++;
            System.out.println("我爱java" + count);
        }
        
        // 下面的代码段被注释掉了,是一个使用while(true)实现的无限循环。
        /* 
        while(true){
            count++;
            System.out.println("我爱java" + count);
        }
        */
    }
}
## 6.嵌套循环

1.概述:循环中还有循环
2.执行流程:
         先执行外层循环,再进入内层循环,内层循环就一直循环,直到内层循环结束,外层循环进入下一次循环,直到外层循环都结束了,整体结束

/**
 * Demo02Nest 类用于展示嵌套循环打印所有分钟和秒的组合。
 */
public class Demo02Nest {
    /**
     * main 方法是程序的入口点。
     * @param args 命令行参数数组,本程序未使用该参数。
     */
    public static void main(String[] args) {
        // 嵌套循环,用于遍历所有60分钟内的时刻组合
        for (int fen = 0; fen < 60; fen++) {
            for (int miao = 0; miao < 60; miao++) {
                // 打印当前分钟和秒数的组合
                System.out.println(fen+"分"+miao+"秒");
            }
       

练习:打印矩形

/**
 * Demo03Nest 类用于展示嵌套循环的基本使用。
 */
public class Demo03Nest {
    /**
     * main 方法是程序的入口点。
     * @param args 命令行参数数组,本示例中未使用。
     */
    public static void main(String[] args) {
        // 控制打印的行数
        for (int i = 0; i < 5; i++) {
            // 控制每行打印的星号个数
            for (int j = 0; j < 5; j++) {
                System.out.print("* ");
            }
            // 每打印完一行,换行
            System.out.println();
        }
    }
}

练习:打印直角三角形


* * 
* * * 
* * * *   

/**
 * Demo04Nest 类用于展示嵌套循环的使用。
 * main 方法是程序的入口点,无参数,无返回值。
 */
public class Demo04Nest {
    /**
     * 程序的主方法。
     * @param args 命令行参数数组。
     */
    public static void main(String[] args) {
        // 外层循环控制打印的行数,从1到4
        for (int i = 1; i < 5; i++) {
            // 内层循环控制每行打印的星号个数,递增式变化
            for (int j = 0;j<i;j++){
                System.out.print("* ");
            }
            // 每打印完一行,换行
            System.out.println();
        }
    }
}
## 7.练习.猜数字小游戏

1.创建Scanner和Random对象
2.调用Random中的nextInt(100)+1在1-100之间随机一个数  rdNumber
3.调用Scanner中的nextInt()方法 键盘录入一个要猜的数   scNumber
4.如果scNumber大于rdNumber,证明猜大了
5.如果scNumber小于rdNumber,证明猜小了
6.如果scNumber等于rdNumber,证明猜中了

/**
 * 此类为一个简单的猜数字游戏的示例程序。
 * 主要功能是让玩家从1到100之间猜一个随机数,程序根据玩家的猜测给出相应提示,直到玩家猜中为止。
 */
public class Demo01Exam {
    public static void main(String[] args) {
        // 初始化随机数生成器和输入扫描器
        Scanner sc = new Scanner(System.in);
        Random rd = new Random();
        
        // 生成一个1到100之间的随机数
        int rdNumber = rd.nextInt(100) + 1;
        
        // 进入猜数字的循环
        while(true){
            // 提示用户输入猜测的数字
            System.out.println("请您猜一个数:");
            int scNumber = sc.nextInt();
            
            // 比较用户猜测的数字与随机数,并给出相应提示
            if (scNumber > rdNumber){
                System.out.println("对不起,您猜大了!");
            }else if (scNumber < rdNumber){
                System.out.println("对不起,您猜小了!");
            }else{
                // 当用户猜中时,给出恭喜信息并结束循环
                System.out.println("恭喜您,猜中了!");
                break;
            }
        }
    }
}

# day05.数组

```java
课前回顾:
   1.Scanner:
    a.导包: import java.util.Scanner
    b.创建对象:Scanner 名字 = new Scanner(System.in)
    c.调用方法:
      nextInt()录入一个整数
      next()录入一个字符串,遇到空格和回车就结束
      nextLine()录入一个字符串,遇到回车就结束
  2.switch:选择语句
    a.格式:
      switch(变量){
          case 常量值1:
              执行语句1;
              break;
          case 常量值2:
              执行语句2;
              break;
          ...
              default:
              执行语句n;
              break;
      }
    b.执行流程:用变量代表的值去精准匹配,配上哪个case就走哪个case对应的执行语句,如果都配不上,就走default
               
    c.没有break:会出现case的穿透性,一直穿透,直到遇到break或者switch结束为止

  3.if...else:
    a.格式:
      if(boolean表达式){
          执行语句1
      }else{
          执行语句2
      }
    b.执行流程:
      先走if后面的boolean表达式,如果是true,就走if后面的执行语句1,否则就走else后面的执行语句2
  4.else...if
    a.格式:
      if(boolean表达式){
          执行语句1
      }else if(boolean表达式){
          执行语句2
      }else if(boolean表达式){
          执行语句3
      }...else{
          执行语句n
      }
    b.执行流程:
      从上到下挨个判断,哪个条件为true,就走哪个if对应的执行语句,以上所有的if都没有匹配上,走else
          
 5.for循环:
   a.格式:
     for(初始化变量;比较;步进表达式){
         循环语句
     }
   b.执行流程:
     先初始化变量,比较,如果是true,走循环语句
     走步进表达式,再比较,如果还是true,继续循环,直到比较为false,循环结束
         
6.while循环:
   a.格式:
     初始化变量;
     while(比较){
         循环语句
         步进表达式
     }
   b.执行流程
     先初始化变量,比较,如果是true,走循环语句
     走步进表达式,再比较,如果还是true,继续循环,直到比较为false,循环结束
       
 7.do...while循环:
   a.格式:
     初始化变量;
     do{
         循环语句
         步进表达式
     }while(比较);
   b.执行流程:
     初始化变量;
     循环语句
     步进表达式
     比较,如果是true,继续循环,直到比较为false
 8.死循环:比较永远是true
 9.嵌套循环:

   先走外层循环,再走内层循环,内层循环就一直循环,直到内层循环结束了,外层循环再进入下一次循环,直到连外层循环都结束了,循环整体结束
       
 10.循环控制关键字:
   break:结束循环
   continue:结束本次循环进入下一次循环
       
 9.Random
   a.概述:java定义好的类
   b.作用:在指定的范围内随机一个数
   c.使用:
     导包-> import java.util.Random
     创建对象-> Random 对象名 = new Random()
     调用方法: 
        对象名.nextInt() 在int的取值范围内随机一个数
        对象名.nextInt(int bound) -> 在0-(bound-1)之间随机

模块五重点:
  1.数组的定义和特点
  2.数组的操作(存数据,取数据,遍历数据)
  3.二维数组(定义,取,存,遍历)
```

# 第一章.数组的定义

1.问题:想将一个数据保存起来,我们可以使用变量,但是变量一次只能存储一个数据,所以我们想能不能一次存多个数据
2.数组概述:是一个容器,数组本身属于引用数据类型
3.作用:一次存储多个数据
4.特点:
        a.既可以存储基本类型的数据,还能存储引用类型的数据
        b.定长(定义数组时长度为多长,最多就能存多少个数据) 
5.定义:
        a.动态初始化:
                数据类型[] 数组名 = new 数据类型[长度]
                数据类型 数组名[] = new 数据类型[长度]    
    
        各部分解释:
                等号左边的数据类型:规定了数组中只能存储什么类型的元素
                【】:代表的是数组,一个【】代表一维数组,两个【】【】代表二维数组    
        数组名:自己取的名字,遵循小驼峰
        new:代表的是创建数组
        等号右边的数据类型:要和等号左边的数据类型一致
      【长度】]:指定数组长度,规定了数组最多能存多少个数据    
        b.静态初始化
                数据类型【】 数组名 = new 数据类型【】{元素1,元素2...}  -> 不推荐使用 
                数据类型 数组名【】 = new 数据类型【】{元素1,元素2...}  -> 不推荐使用            c.简化的静态初始化:数据类型【】 数组名 = {元素1,元素2...}-> 推荐使用
6.静态初始化、动态初始化区别:
        a.动态初始化:定义的时候只指定了长度,没有存具体的数据
                当只知道长度,但不知道具体存啥数据时可以使用动态初始化
        b.静态初始化:定义的时候就直接知道存啥了   

/**
 * Demo01Array类,演示了数组的初始化方法。
 */
public class Demo01Array {
    /**
     * main方法,程序的入口点。
     * @param args 命令行参数数组。
     */
    public static void main(String[] args) {
        // 动态初始化数组,指定数组长度,元素初始值未指定。
        int[] arr1 = new int[3];
        String[] arr2 = new String[3];

        // 静态初始化数组,指定数组长度并一次性赋初值。
        int[] arr3 = new int[]{1,2,3,4,5};

        // 简化静态初始化,不显示数组长度,直接在声明时赋值。
        int[] arr4 = {1,2,3,4,5};

        // 字符串数组的静态初始化,可以用于历史人物等枚举。
        String[] arr5 = {"乾隆","和珅","纪晓岚"};
    }
}

# 第二章.数组操作

## 1.获取数组的长度

1.格式:

  数组名.length

2.注意:length后面不要带小括号,因为length不是一个方法,而是数组中的一个属性

/**
 * Demo01Array类,演示了如何定义和使用字符串数组。
 */
public class Demo01Array {
    /**
     * main方法,程序的入口点。
     * @param args 命令行参数,本程序未使用该参数。
     */
    public static void main(String[] args) {
        // 定义一个字符串类型的数组,包含了一些著名的动画或特摄片名称
        String[] arr1 = {"迪迦奥特曼","猫和老鼠","花园宝宝","海绵宝宝","圣斗士","百变小樱魔术卡","熊出没"};
        // 获取数组的长度
        int len = arr1.length;
        // 打印数组的长度
        System.out.println("len = " + len);
    }
}

## 2.索引

1.概述:元素在数组中存储的位置  
2.特点:
        a.索引唯一
        b.索引都是从0开始的,最大索引是数组长度-1 
3.注意:
        我们将来操作元素,必须通过索引来操作
        存数据,要指定索引
        取数据,要指定索引
        查数据,要指定索引

## 3.存储元素

1.格式:

 数组名[索引值] = 值 -> 将等号右边的值放到数组指定的索引位置上
/**
 * Demo02Array类展示了数组的基本使用方法。
 */
public class Demo02Array {
    /**
     * main方法是程序的入口点。
     * @param args 命令行参数数组。
     */
    public static void main(String[] args) {
        // 创建一个整型数组并初始化
        int[] arr = new int[3];
        arr[0] = 100; // 将100存到数组的0索引上
        arr[1] = 200; // 将200存到数组的1索引上
        arr[2] = 300; // 将300存到数组的2索引上
        
        // 下面的代码演示了创建并初始化一个字符串数组
        System.out.println("============================");
        
        String[] arr1 = new String[3]; // 创建一个字符串数组
        arr1[0] = "东方不败"; // 将字符串"东方不败"存到数组的0索引上
        arr1[1] = "岳不群"; // 将字符串"岳不群"存到数组的1索引上
        arr1[2] = "林平之"; // 将字符串"林平之"存到数组的2索引上
    }
}
public class Demo03Array {
    /**
     * 主函数:通过键盘输入三个整数,将它们存储到数组中。
     * @param args 命令行参数(未使用)
     */
    public static void main(String[] args) {
        // 创建一个能存储3个整数的数组
        int[] arr = new int[3];

        // 使用Scanner类从键盘读取输入
        Scanner sc = new Scanner(System.in);

        // 使用for循环逐个读取三个整数并存储到数组中
        for (int i = 0; i < arr.length; i++) {
            arr[i] = sc.nextInt();
        }
    }
}
/**
 * Demo04Array类,演示了如何使用数组和随机数。
 */
public class Demo04Array {
    /**
     * main方法,程序的入口点。
     * @param args 命令行参数。
     */
    public static void main(String[] args) {
        // 定义一个长度为3的整型数组
        int[] arr = new int[3];
        // 创建Random对象用于生成随机数
        Random rd = new Random();

        // 使用循环为数组的每个元素赋值为0到9之间的随机数
        for (int i = 0;i<arr.length;i++){
            // 为数组中的每个位置生成一个随机数并赋值
            arr[i] = rd.nextInt(10);
        }
    }
}

## 4.获取元素

1.地址值:
        数组在内存中的身份证号,唯一标识,我们可以通过这个唯一标识到内存中准确找到这个数,从而操作这个数组中的数据
2.注意:
        a.直接输出数组名,会直接输出数组在内存中的地址值 
        b.如果数组中没有存元素,那么直接获取索引上对应的元素也是有值的,只不过不是我们存储的数据,而是数组中的元素默认值
        整数: 0
        小数: 0.0
        字符: '\u0000' -> 空白字符 -> 对应的int值是0
        布尔: false
        引用: null    

/**
 * Demo04Array类,演示了如何使用数组和随机数。
 */
public class Demo04Array {
    /**
     * main方法,程序的入口点。
     * @param args 命令行参数。
     */
    public static void main(String[] args) {
        // 定义一个长度为3的整型数组
        int[] arr = new int[3];
        // 创建Random对象用于生成随机数
        Random rd = new Random();

        // 使用循环为数组的每个元素赋值为0到9之间的随机数
        for (int i = 0;i<arr.length;i++){
            // 为数组的每个位置生成一个随机数并赋值
            arr[i] = rd.nextInt(10);
        }
    }
}

/**
 * Demo06Array类展示了如何将一个数组中的数据复制到另一个数组中。
 */
public class Demo06Array {
    /**
     * main方法是程序的入口点。
     * @param args 命令行参数。
     */
    public static void main(String[] args) {
        // 初始化原始数组arr
        int[] arr = {1,2,3,4,5,6};
        
        // 需求:将arr数组中的数据复制到新数组newArr中
        // 创建一个与arr数组长度相同的新数组newArr
        int[] newArr = new int[arr.length];

        // 输出新数组newArr各个位置的默认值(0)
        System.out.println(newArr[0]);
        System.out.println(newArr[1]);
        System.out.println(newArr[2]);
        System.out.println(newArr[3]);
        System.out.println(newArr[4]);
        System.out.println(newArr[5]);

        // 将arr数组的元素逐个复制到newArr数组中
        newArr[0] = arr[0];
        newArr[1] = arr[1];
        newArr[2] = arr[2];
        newArr[3] = arr[3];
        newArr[4] = arr[4];
        newArr[5] = arr[5];

        // 输出复制后的新数组newArr的内容
        System.out.println(newArr[0]);
        System.out.println(newArr[1]);
        System.out.println(newArr[2]);
        System.out.println(newArr[3]);
        System.out.println(newArr[4]);
        System.out.println(newArr[5]);
    }
}
arr[0] = arr1[0] 

        如果数组名[索引值]在等号右边就代表获取
        如果数组名[索引值]在等号左边就代表存值

比如 :

int element = arr[0] -> 获取0索引上的元素,赋值给一个变量
arr[0] = 100 -> 将100存储到0索引上
arr[0] = arr1[0]  -> 将arr1的0索引上的元素获取出来,赋值给等号左边arr的0索引上

## 5.遍历数组

1.遍历:将元素从数组中一个一个的获取出来

/**
 * Demo07Array类展示了如何使用数组并遍历数组中的元素。
 */
public class Demo07Array {
    /**
     * main方法是程序的入口点。
     * @param args 命令行参数。
     */
    public static void main(String[] args) {
        // 创建并初始化一个整型数组
        int[] arr = {1, 2, 3, 4, 5, 6};
        
        // 以下两种for循环用来遍历数组arr,输出每个元素
        // 第一种遍历方式,已注释
        /*for (int i = 0; i < 6; i++){
            System.out.println(arr[i]);
        }*/

        // 第二种遍历方式,使用数组的length属性
        /* for (int i = 0; i < arr.length; i++){
            System.out.println(arr[i]);
        }*/
        
        // 快速遍历数组的方法,通过for循环遍历数组并输出每个元素
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

快速遍历快捷键::数组名.for i

/**
 * Demo08Array类展示了如何将一个数组中的数据复制到另一个数组中。
 */
public class Demo08Array {
    /**
     * main方法是程序的入口点。
     * @param args 命令行参数。
     */
    public static void main(String[] args) {
        // 初始化原始数组arr
        int[] arr = {1,2,3,4,5,6};
        // 需求:将arr数组中的数据复制到另一个数组newArr中
        
        // 创建一个与arr数组长度相同的新数组newArr,如果我们想将arr中的数据复制到新数组中,那么新数组的长度就应该是arr数组的长度
        int[] newArr = new int[arr.length];
        
        // 输出新数组newArr各元素的默认值(0)
        System.out.println(newArr[0]);
        System.out.println(newArr[1]);
        System.out.println(newArr[2]);
        System.out.println(newArr[3]);
        System.out.println(newArr[4]);
        System.out.println(newArr[5]);

/*      //将arr数组指定索引位置上的元素获取出来放到等号左边newArr数组的指定索引位置上
        newArr[0] = arr[0];
        newArr[1] = arr[1];
        newArr[2] = arr[2];
        newArr[3] = arr[3];
        newArr[4] = arr[4];
*/
        
        // 使用循环将arr数组中的元素复制到newArr数组中
        for (int i = 0; i < arr.length; i++) {
            newArr[i] = arr[i];
        }
        
        // 遍历newArr数组并输出所有元素
        for (int i = 0; i < newArr.length; i++) {
            System.out.println(newArr[i]);
        }
    }
}

# 第三章.操作数组时两个常见的问题

## 1.数组索引越界异常_ArrayIndexOutOfBoundsException1.原因:

        操作的索引超出了数组索引范围了

/**
 * Demo09Array类展示了数组的基本使用方法。
 */
public class Demo09Array {
    /**
     * main方法是程序的入口点。
     * @param args 命令行参数数组。
     */
    public static void main(String[] args) {
        // 创建一个整型数组arr,长度为3
        int[] arr = new int[3];
        // 为数组的每个元素赋值
        arr[0] = 100;
        arr[1] = 200;
        arr[2] = 300;
        
        // 下面的代码尝试访问数组的越界索引,会被编译器阻止
        //arr[3] = 400;//索引3超出了arr的索引范围

        //arr[-1] = 1000;//索引-1超出了arr的索引范围

        // 使用for循环遍历数组,此处循环会多访问一次,导致出现越界异常
        for (int i = 0; i <= arr.length; i++) {
            System.out.println(arr[i]);//索引3超出了arr的索引范围
        }
    }
}

## 2.空指针异常_NullPointerException

1.原因:当一个对象为null时,再调用此对象中的其他成员

/**
 * Demo10Array类展示了数组使用的基本示例。
 */
public class Demo10Array {
    /**
     * main方法是程序的入口点。
     * @param args 命令行参数数组。
     */
    public static void main(String[] args) {

        // 创建一个长度为3的整型数组
        int[] arr = new int[3];
        // 输出数组的长度
        System.out.println(arr.length);//3

        // 将数组引用设置为null
        arr = null;
        // 尝试访问null数组的长度,将抛出NullPointerException
        System.out.println(arr.length);//NullPointerException
    }
}

以上两个问题我们只需要知道原因即可

# 第四章.数组练习

## 1.练习

第一题:需求:求出数组中的元素最大值
步骤:
  1.定义一个max,接收两个元素之间的较大值
  2.遍历数组,将每一个元素获取出来进行比较
  3.判断,如果max小于遍历出来的元素,证明遍历出来的元素大,将大的元素赋值给max
  4.直接输出max    

/**
 * Demo01GetMax类用于演示获取数组中的最大值。
 */
public class Demo01GetMax {
    /**
     * main方法是程序的入口点。
     * @param args 命令行参数数组。
     */
    public static void main(String[] args) {
        // 定义一个整型数组
        int[] arr = {5,3,5,7,4,6,8,9};
        // 初始化max为数组的第一个元素
        int max = arr[0];
        // 遍历数组,从第二个元素开始比较
        for (int i = 1; i < arr.length; i++) {
            // 如果当前元素大于max,则更新max
            if (max<arr[i]){
                max = arr[i];
            }
        }
        // 输出最大值
        System.out.println("max = " + max);
    }
}

## 2.练习

```java
随机产生10个[0,100]之间整数,统计既是3又是5,但不是7的倍数的个数
步骤:
 1.创建一个Random对象,用于搞随机数
 2.定义一个数组,长度为10
 3.定义一个变量count,用来统计个数
 4.遍历数组,判断元素是否符合指定条件,如果符合,count++
 5.输出count    

/**
 * 此类用于演示对数组中满足特定条件的元素进行计数的方法。
 */
public class Demo02Count {
    /**
     * 主函数入口。
     * @param args 命令行参数(未使用)
     */
    public static void main(String[] args) {
        // 创建一个Random对象,用于生成随机数
        Random rd = new Random();
        // 定义一个长度为10的整型数组
        int[] arr = new int[10];
        // 定义变量count,用于统计满足条件的元素个数
        int count = 0;

        // 使用随机数填充数组
        for (int i = 0; i < arr.length; i++) {
            arr[i] = rd.nextInt(101);
        }

        // 遍历数组,统计满足条件(能同时被3和5整除,但不能被7整除)的元素个数
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] % 3 == 0 && arr[i] % 5 == 0 && arr[i] % 7 != 0) {
                count++;
            }
        }
        // 输出满足条件的元素个数
        System.out.println("count = " + count);
    }
}

## 3.练习

用一个数组存储本组学员的姓名,从键盘输入,并遍历显示

/**
 * Demo03Print类用于演示通过键盘输入多个学员姓名,并将这些姓名打印出来。
 */
public class Demo03Print {
    /**
     * main函数是程序的入口点。
     * @param args 命令行参数,本程序未使用该参数。
     */
    public static void main(String[] args) {
        // 创建一个String类型的数组,用于存储学员姓名
        String[] arr = new String[3];
        // 创建Scanner对象,用于从System.in读取输入
        Scanner sc = new Scanner(System.in);
        
        // 循环,请求用户输入每个学员的姓名,并存储到数组中
        for (int i = 0; i < arr.length; i++) {
            // 提示用户输入第i+1个学员的姓名
            System.out.println("请您输入第"+(i+1)+"个学员姓名:");
            // 读取用户输入的姓名,并存储到数组中
            arr[i] = sc.next();
        }

        // 循环,打印出所有输入的学员姓名
        for (int i = 0; i < arr.length; i++) {
            // 打印出第i个学员的姓名
            System.out.println(arr[i]);
        }
    }
}

## 4.练习
需求:
  1.定义一个数组 int[] arr = {1,2,3,4}
  2.遍历数组,输出元素按照[1,2,3,4]

package com.atguigu.helloworld;
import java.util.Random;
import java.util.Scanner;
public class Demo04Array {

    public static void main(String[] args) {
// 定义一个整数数组,初始化为 [1, 2, 3, 4]
        int[] arr = {1, 2, 3, 4};

// 遍历数组并按照顺序输出每个元素
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]);
            // 在最后一个元素后不再添加逗号与空格
            if (i < arr.length - 1) {
                System.out.print(", ");
            }
        }
    }
}

## 5.练习

需求:随机50个1-100之间的整数,统计偶数个数

/**
 * 计算数组中偶数的个数
 * 该程序演示了如何创建一个数组,填充它以随机整数,并计算其中偶数的个数。
 */
public class Demo05Count {
    public static void main(String[] args) {
        // 初始化一个长度为50的整型数组
        int[] arr = new int[50];
        // 创建Random对象以生成随机数
        Random rd = new Random();
        // 使用循环为数组的每个元素分配一个1到100之间的随机数
        for (int i = 0; i < arr.length; i++) {
            arr[i] = rd.nextInt(100) + 1;
        }

        // 定义变量count用于记录数组中偶数的个数
        int count = 0;
        // 遍历数组,统计偶数的个数
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] % 2 == 0) {
                count++;
            }
        }

        // 打印出数组中偶数的个数
        System.out.println("count = " + count);
    }
}


//    public static void main(String[] args) {
//        int count = 0;
//        Random rd = new Random();
//        int nums = rd.nextInt(100);
//        for (int i = 0; i < 50; i++) {
//            nums = rd.nextInt(100);
//            System.out.println(nums);
//            if (nums %2 == 0) {
//                count++;
//                System.out.println("是偶数"+ "I="+i);
//            }
//            //System.out.println();
//        }
//        System.out.println("偶数个数为:" + count  );
//    }
//}

## 6.练习

```java
键盘录入一个整数,找出整数在数组中存储的索引位置

步骤:
  1.创建Scanner对象
  2.定义数组,随便存几个数据
  3.遍历数组,在遍历的过程中判断是否和录入的数相等,如果相等,输出索引

public class Demo06Search {
    public static void main(String[] args) {
        //1.创建Scanner对象
        Scanner sc = new Scanner(System.in);
        //2.定义数组,随便存几个数据
        int[] arr = {11,22,33,44,55,66,22};
        int data = sc.nextInt();
        //3.遍历数组,在遍历的过程中判断是否和录入的数相等,如果相等,输出索引
        for (int i = 0; i < arr.length; i++) {
            if (data==arr[i]){
                System.out.println(i);
            }
        }
    }
}

问题升级:如果查不到,输出-1,代表没有查到

    /**
     * 在给定的整型数组中搜索指定的元素,并输出其索引位置。
     * 如果元素不存在,则输出-1。
     */
    public class Demo06Search {
        public static void main(String[] args) {
            // 创建Scanner对象,用于从控制台接收输入
            Scanner sc = new Scanner(System.in);
            // 定义数组,存储待搜索的数据
            int[] arr = {11,22,33,44,55,66,22};
            // 接收用户输入的搜索数据
            int data = sc.nextInt();

            // 定义标志变量,用于表示是否找到搜索的数据
            int flag = 0;

            // 遍历数组,搜索指定的数据,遍历数组,在遍历的过程中判断是否和录入的数相等,如果相等,输出索引
            for (int i = 0; i < arr.length; i++) {
                // 如果当前元素与搜索数据相等,输出索引并设置标志变量
                if (data == arr[i]){
                    System.out.println(i);
                    flag++;
                }
            }

            // 如果遍历完整个数组仍未找到数据,输出-1,4.判断flag是否还为0,如果遍历完,比较完之后,出了for循环,flag还是0,证明在遍历的过程中没有走过if
            if (flag == 0){
                System.out.println(-1);
            }
        }
    }

## 7.练习_数组复制

```

```

## 8.练习_数组扩容```
数组扩容
    
需求:
        定义一个数组:int【】 arr1 = {1,2,3,4,5}
        将数组由原来的长度扩容到10

public class Demo04Array {
    /**
     * 扩容数组
     * 将原数组的元素复制到新创建的一个长度为10的数组中,并将新数组的引用赋值给原数组。
     */
    public static void main(String[] args) {
        int[] oldArr = {1,2,3,4,5};  // 定义原数组

        // 创建新数组
        int[] newArr = new int[10];

        // 将原数组中的元素复制到新数组
        for (int i = 0; i < oldArr.length; i++) {
            newArr[i] = oldArr[i];
        }

        // 更新原数组地址引用为新数组地址
        oldArr = newArr;

        // 输出新数组的长度
        System.out.println(oldArr.length);

        System.out.println("==================");

        // 遍历并打印扩容后的原数组元素
        for (int i = 0; i < oldArr.length; i++) {
            System.out.println(oldArr[i]);
        }
    }
}

## 9.练习_数组合并```java
数组合并

int[] arr1 = {1,2,3}
int[] arr2 = {4,5,6}
    /**
     * 此示例演示了如何将两个整型数组合并为一个新数组。
     * 主函数中不接受参数,也不返回值。
     */
    public class Demo05Array {
        public static void main(String[] args) {
            int[] arr1 = {1,2,3};  // 定义并初始化第一个整型数组
            int[] arr2 = {4,5,6};  // 定义并初始化第二个整型数组
            
            // 创建新数组以存放两个数组的内容
            int[] newArr = new int[arr1.length+arr2.length];

            // 将arr1的元素复制到新数组newArr中
            for (int i = 0; i < arr1.length; i++) {
                newArr[i] = arr1[i];
            }

            // 计算arr2元素应从newArr的哪个索引位置开始保存
//由于已经保存了arr1的三个元素,所以我们保存arr2的元素时,就不能从索引0开始了,不然从arr1中保存的元素会被arr2的元素覆盖
//arr2的元素需要从newArr的索引3开始保存
            int len = arr1.length;

            // 将arr2的元素复制到新数组newArr中,从确定的位置开始
            for (int i = 0; i < arr2.length; i++) {
//newArr[3+0] = arr2[0] ;i++
//newArr[3+1] = arr2[1] ;i++
//newArr[3+2] = arr2[2] 

                newArr[len+i] = arr2[i];
            }

            // 遍历并打印新数组newArr的所有元素
            for (int i = 0; i < newArr.length; i++) {
                System.out.print(newArr[i]+"  ");
            }
        }
    }

# 第五章.内存图

1.内存:可以理解"内存条",任何程序,软件运行起来都会在内存中运行,占用内存,在java的世界中,将内存分为了5大块
    
2.分为哪5大块
  栈(重点)(Stack)
    主要运行方法,方法的运行都会去栈内存中运行,运行完毕之后,需要"弹栈",腾空间
    
  堆(重点):(Heap)
    每new一次,都会在堆内存中开辟空间,并为此空间自动分配一个地址值
    堆中的数据都是有默认值的
    整数:0
    小数:0.0
    字符: '\u0000'
    布尔:false
    引用:null    

方法区(重点)(Method Area)
        代码的"预备区",记录了类的信息以及方法的信息

        方法区中主要保存class文件以及其中的信息

        代码运行之前,需要先进内存(方法区)

本地方法栈(了解):(Native Method Stack)

        专门运行native方法(本地方法)
        本地方法可以理解为对java功能的扩充 
        有很多功能java语言实现不了,所以就需要依靠本地方法完成

寄存器(了解)(pc ) -> 跟CPU有关

  
        

## 1.一个数组内存图

## 2.两个数组内存图

我们创建了两个数组,在堆内存中开辟了两个不同的空间,此时修改一个数组中的元素不会影响到另外一个数组中的数据

## 3.两个数组指向同一片内存空间

arr2不是new出来的,是arr1直接赋值的,arr1在内存中保存的是地址值,给了arr2,那么arr2的地址值和arr1就是一样的
所以此时arr1和arr2指向了堆内存中的同一片空间(同一个地址值,同一个数组),此时改变一个数组中的元素会影响到另外一个数组

# 第六章.二维数组

## 1.二维数组的定义格式

1.概述:数组中的套多个数组
2.定义格式
        a.动态初始化
                数据类型【】【】 数组名 = new 数据类型【m】【n】
                数据类型 数组名【】【】 = new 数据类型【m】【n】
                数据类型【】 数组名【】 = new 数据类型【m】【n】
    
                m:代表的是二维数组的长度
                n:代表的是二维数组中每一个一维数组的长度
    
                数据类型【】【】 数组名 = new 数据类型【m】【】 -> 二维数组中的一维数组没有被创建  
        
        b.静态初始化
                数据类型【】【】 数组名 = new 数据类型【】【】{{元素1,元素2...},{元素1,元素2...},{元素1,元素2...}}
                数据类型 数组名【】【】 = new 数据类型【】【】{{元素1,元素2...},{元素1,元素2...},{元素1,元素2...}}
                数据类型【】 数组名【】 = new 数据类型【】【】{{元素1,元素2...},{元素1,元素2...},{元素1,元素2...}}

        c.简化静态初始化:
                数据类型【】 【】数组名 = {{元素1,元素2...},{元素1,元素2...},{元素1,元素2...}}
                数据类型 数组名【】【】 = {{元素1,元素2...},{元素1,元素2...},{元素1,元素2...}}
                数据类型【】 数组名【】 = {{元素1,元素2...},{元素1,元素2...},{元素1,元素2...}}

/**
 * Demo01Array类,演示了多维数组的声明和使用。
 */
public class Demo01Array {
    /**
     * main方法,程序的入口点。
     * @param args 命令行参数数组。
     */
    public static void main(String[] args) {
        // 声明一个2x2的二维整型数组
        int[][] arr1 = new int[2][2];

        // 声明一个行长度不固定的二维整型数组
        int[][] arr2 = new int[2][];

        // 打印分隔线
        System.out.println("======================");

        // 使用初始化列表声明一个二维字符串数组,并初始化元素
        String[][] arr3 = {{"孙悟空","唐僧"},{"刘备","关羽","张飞"},{"宋江"},{"林黛玉","贾宝玉","王熙凤","薛宝钗"}};
    }
}

## 2.获取二维数组长度

1.格式:
  数组名.length
      
2.获取每一个一维数组长度,需要先遍历二维数组,将每一个一维数组从二维数组中拿出来     

/**
 * Demo02Array类,演示了二维数组的基本操作。
 */
public class Demo02Array {
    /**
     * main方法,程序的入口点。
     * @param args 命令行参数,本程序未使用。
     */
    public static void main(String[] args) {
        // 定义一个二维字符串数组,表示人员姓名
        String[][] arr = {{"张三","李四"},{"王五","赵六","田七"},{"猪八","牛九"}};
        // 输出二维数组的行数
        System.out.println(arr.length);
        // 遍历二维数组,输出每行包含的元素个数
        for (int i = 0; i < arr.length; i++) {
            // arr[i]代表的是每一个一维数组
            System.out.println(arr[i].length);
        }
    }
}

## 3.获取二维数组中的元素

1.格式:
  数组名【i】【j】
      
  i:代表的是一维数组在二维数组中的索引位置
  j:代表的是元素在一维数组中的索引位置

/**
 * Demo03Array类:演示二维数组的使用。
 */
public class Demo03Array {
    /**
     * main方法:程序的入口点。
     * @param args 命令行参数数组。
     */
    public static void main(String[] args) {
        // 创建一个二维数组,存储姓名信息
        String[][] arr = {{"张三","李四"},{"王五","赵六","田七"},{"猪八","牛九"}};
        
        // 输出二维数组中指定位置的元素
        System.out.println(arr[0][0]); // 输出第一行第一列的元素
        System.out.println(arr[2][0]); // 输出第三行第一列的元素
        System.out.println(arr[1][1]); // 输出第二行第二列的元素
    }
}

## 4.二维数组中存储元素

1.格式:
  数组名【i】【j】 = 值
      
  i:代表的是一维数组在二维数组中的索引位置
  j:代表的是元素在一维数组中的索引位置

/**
 * Demo04Array类展示了如何创建和使用二维数组。
 * 该类没有参数和返回值,因为它是一个包含main方法的程序入口类。
 */
public class Demo04Array {
    /**
     * main方法是程序的入口点。
     * args参数是命令行传入的参数数组。
     */
    public static void main(String[] args) {
        // 创建一个2x2的字符串二维数组
        String[][] arr = new String[2][2];
        
        // 初始化数组元素
        arr[0][0] = "张飞"; 
        arr[0][1] = "李逵"; 
        arr[1][0] = "刘备"; 
        arr[1][1] = "宋江"; 

        // 打印数组元素
        System.out.println(arr[0][0]);
        System.out.println(arr[0][1]);
        System.out.println(arr[1][0]);
        System.out.println(arr[1][1]);
    }
}

## 5.二维数组的遍历

1.先遍历二维数组,将每一个一维数组遍历出来
2.再遍历每一个一维数组,将元素获取出来

/**
 * Demo05Array类展示了如何创建和遍历二维数组。
 * 主函数中创建了一个包含人物名字的二维字符串数组,并通过嵌套循环打印出数组中的所有元素。
 */
public class Demo05Array {
    public static void main(String[] args) {
        // 创建一个2x2的二维字符串数组,并初始化元素
        String[][] arr = new String[2][2];
        arr[0][0] = "张飞";
        arr[0][1] = "李逵";
        arr[1][0] = "刘备";
        arr[1][1] = "宋江";

        // 遍历二维数组,打印出所有元素
        for (int i = 0; i < arr.length; i++) {
            // 内层循环遍历每一个一维数组的元素
            for (int j = 0; j < arr[i].length; j++) {
                System.out.println(arr[i][j]);
            }
        }
    }
}

## 6.二维数组内存图

/**
 * Demo06Array类展示了如何使用二维数组。
 */
public class Demo06Array {
    /**
     * main方法是程序的入口点。
     * @param args 命令行参数。
     */
    public static void main(String[] args) {
        // 创建一个二维数组arr1,其第一维的长度为3
        int[][] arr1 = new int[3][];

        // 为arr1的第二个元素(索引为1)分配一个包含1,2,3的数组
        arr1[1] = new int[]{1,2,3};

        // 为arr1的第三个元素(索引为2)分配一个长度为3的数组
        arr1[2] = new int[3];

        // 设置arr1的第三个元素的第二个值(索引为2[1])为100
        arr1[2][1] = 100;
    }
}

# 模块六_方法  

 模块五的重点回顾:
   1.概述:容器,本身属于引用数据类型
   2.特点:
     a.定长
     b.既可以存储基本数据类型的数据,还可以存储引用数据类型的数据
   3.定义:
     动态初始化: 数据类型[] 数组名 = new 数据类型[长度]
     静态初始化: 数据类型[] 数组名 = {元素1,元素2...}
   4.数组操作:
     a.获取数组长度: 数组名.length
     b.存储数据: 数组名[索引值] = 元素 -> 将元素存储到数组指定的索引位置上
     c.获取元素: 数组名[索引值]
     d.遍历: 数组名.fori
     e.索引:指的是元素在数组中存储的位置
       从0开始,最大索引是数组.length-1
       唯一,不能重复
   5.操作数组时容易出现的异常
     a.数组索引越界异常:ArrayIndexOutOfBoundsException
       原因:操作的索引超出了数组索引范围
     b.空指针异常:NullPointerException
       原因:对象为null,然后再去操作此对象
           
  6.内存:
    a.栈:方法的运行在栈
    b.堆:数组,对象都在堆,而且每new一次都会在堆中开辟一个空间,堆内存会为此空间分配一个地址值
    c.方法区:代码运行之前的预备区,存储class文件
    d.本地方法栈
    e.寄存器
        
7.二维数组概述:数组中套了多个一维数组
        a.动态初始化定义:数据类型[][] 数组名 = new 数据类型[m][n]
                m:代表的是二维数组长度
                n:代表的是每一个一维数组长度
          
    b.静态初始化定义(简化形式):
      数据类型[][] 数组名 = {{元素1,元素2...},{元素1,元素2...},{元素1,元素2...}...}

8.二维数组操作:
        a.获取长度:数组名.length
        b.存元素: 数组名[i][j] = 值
                i:代表的是一维数组在二维数组中的索引位置
                j:代表的是元素在一维数组中的索引位置
         c.获取元素:数组名[i][j]
        d.遍历:嵌套for 先将一维数组从二维数组中遍历出来,然后再遍历每一个一维数组

模块六重点:
  all

# 第一章.方法的使用

## 1.方法介绍以及简单方法定义(无参无返回值)

1.问题描述:
        之前所有的代码都在main方法中写,如果我们将来将所有功能的代码都放到main方法中,会显得main方法代码太多,太乱,太臃肿-> 不好维护
      
        解决:将不同功能的代码放到不同的方法中,想执行某个功能,直接调用方法名就行了,对应的代码就自动执行起来了
        将来维护的时候,直接找到对应的方法,就可以对其直接修改维护
      
2.方法:
        拥有功能性代码的代码块
        将不同的功能放在不同的方法中,给每个方法取个名字,直接调用方法名,对应的方法就执行起来了,好维护
      
3.通用定义格式:
        修饰符 返回值类型 方法名(参数){
                方法体
                return 结果
  }

4.通过通用格式,分成四种方法来学习:
        a.无参无返回值方法
        b.有参无返回值方法
        c.无参有返回值方法
        d.有参有返回值方法

1.无参无返回值方法定义:
      

  public static void 方法名(){
                方法体 -> 实现此方法的具体代码
        }

2.调用:直接调用
  在其他方法中: 方法名()
      
3.注意事项:
  a.void关键字代表无返回值,写了void,就不要在方法中写return 结果
  b.方法不调用不执行, main方法是jvm调用的
  c.方法之间不能互相嵌套,方法之间是平级关系
  d.方法的执行顺序只和调用顺序有关    

/**
 * Demo01Method 类展示了从种植食物到烹饪食物再到享用食物的过程。
 */
public class Demo01Method {
    /**
     * main 方法是程序的入口点。
     * @param args 命令行参数数组。
     */
    public static void main(String[] args) {
        // 农民伯伯的工作流程
        farmer();
        // 厨师的烹饪流程
        cook();
        // 我们自己的用餐流程
        me();
        // 再次烹饪,可能是为了满足更多人的需求
        cook();
    }

    /**
     * farmer 方法描述了农民伯伯从播种到收割的整个种植过程。
     */
    public static void farmer(){
        System.out.println("播种");
        System.out.println("施肥");
        System.out.println("拔草");
        System.out.println("浇水");
        System.out.println("除虫");
        System.out.println("收割");
    }

    /**
     * cook 方法描述了厨师从洗菜到上菜的整个烹饪过程。
     */
    public static void cook(){
        System.out.println("洗菜");
        System.out.println("切菜");
        System.out.println("炒菜");
        System.out.println("装盘");
        System.out.println("上菜");
    }

    /**
     * me 方法描述了我们自己从洗手到吃菜的用餐过程。
     */
    public static void me(){
        System.out.println("洗手");
        System.out.println("吃菜");
    }
}


定义一个方法,实现两个整数相加

/**
 * Demo02Method类,包含用于演示方法的代码。
 */
public class Demo02Method {
    /**
     * 程序的主入口函数。
     * @param args 命令行参数,本示例中未使用。
     */
    public static void main(String[] args) {
        // 调用sum方法进行加法演示
        sum();
        // 输出一段文本
        System.out.println("哈哈哈哈哈");
    }
    
    /**
     * 进行两数相加并输出结果的方法。
     * 该方法没有参数和返回值,旨在演示加法操作并输出结果。
     */
    public static void sum(){
        // 定义两个整数并进行加法运算
        int a = 10;
        int b = 20;
        int sum = a+b;
        // 将运算结果输出到控制台
        System.out.println("sum = " + sum);
    }
}

## 2.无参数无返回值的方法执行流程

<img src="img/1699353749750.png" alt="1699353749750" style="zoom:80%;" />

> <img src="img/1699410063398.png" alt="1699410063398" style="zoom:80%;" />

## 3.方法定义各部分解释

```java
1.通用格式:
  修饰符 返回值类型 方法名(参数){
      方法体
      return 结果
  }

2.各部分解释:
  a.修饰符: public static
  b.返回值类型:
    该方法最终返回的结果的数据类型
        比如: return 1 -> 方法上的返回值类型写int
             return 2.5 -> 方法上的返回值类型写double
             return "" -> 方法上的返回值类型写String
    如果没有返回值,不要写具体的返回值类型了,要写void
            
            
  c.方法名:见名知意(小驼峰式)
  d.参数:进入到方法内部参与执行的数据(数据类型 变量名,数据类型 变量名)
  e.方法体:实现该方法的具体代码    
  f.return 结果: 如果有返回值,可以利用return 将结果返回  
```

<img src="img/1699410639842.png" alt="1699410639842" style="zoom:80%;" />

## 4.有参数无返回值的方法定义和执行流程

```java
1.格式:
  public static void 方法名(数据类型 变量名){
      方法体
  }

2.调用:
  直接调用:方法名(具体的值) -> 调用的时候要给参数赋值 
```

```java
需求:定义一个方法,实现两个整数相加
```

```java
public class Demo03Method {
    public static void main(String[] args) {
       sum(10,20);
    }

    public static void sum(int a,int b){
        int sum = a+b;
        System.out.println("sum = " + sum);
    }
}

```

<img src="img/1699412622843.png" alt="1699412622843" style="zoom:80%;" />

## 5.无参数有返回值定义以及执行流程

```java
1.格式:
  public static 返回值类型 方法名(){
      方法体
      return 结果
  }

2.调用: 返回值返回给了谁? 哪里调用返回给哪里
  a.打印调用:sout(方法名()) -> 不推荐使用
  b.赋值调用:调用完之后用一个变量接收返回值结果 -> 极力推荐
    数据类型 变量名 = 方法名()
```

```java
需求:定义一个方法,实现两个整数相加,将结果返回
```

```java
public class Demo04Method {
    public static void main(String[] args) {
        //打印调用 -> 涛哥不推荐
        System.out.println(sum());

        //赋值调用-> 极力推荐
        int result = sum();
        System.out.println("result = " + result);

    }

    public static int sum(){
        int a = 10;
        int b = 20;
        int sum = a+b;
        return sum;
        //return a+b;
    }
}

```

![1699413838812](img/1699413838812.png)

## 6.有参数有返回值定义以及执行流程

```java
1.格式:
  public static 返回值类型 方法名(参数){
      方法体
      return 结果
  }

2.调用:
  a.打印调用:
    sout(方法名(具体的值))
        
  b.赋值调用(极力推荐)
    数据类型 变量名 = 方法名(具体的值)    
```

```java
需求:定义一个方法,实现两个整数相加,将结果返回
```

```java
public class Demo05Method {
    public static void main(String[] args) {
        int sum = sum(10, 20);
        System.out.println("sum = " + sum);
    }
    public static int sum(int a,int b){
        int sum = a+b;
        return sum;
    }
}

import java.util.Scanner;

public class IntegerAddition {

    /**
     * 从用户输入获取两个整数,计算它们的和,并返回结果。
     *
     * @return 两个输入整数之和。
     */
    public static int addTwoIntegersFromUserInput() {
        Scanner scanner = new Scanner(System.in);

        // 获取第一个整数输入
        System.out.println("请输入第一个整数:");
        int num1 = scanner.nextInt();

        // 获取第二个整数输入
        System.out.println("请输入第二个整数:");
        int num2 = scanner.nextInt();

        // 计算两数之和
        int sum = num1 + num2;

        return sum;
    }

    public static void main(String[] args) {
        // 调用方法,获取并打印两数之和
        int result = addTwoIntegersFromUserInput();
        System.out.println("两数之和为: " + result);
    }
}

<img src="img/1699414227291.png" alt="1699414227291" style="zoom:80%;" />

## 7.形式参数和实际参数区别

```java
1.形式参数(形参):在定义方法的时候形式上定义的参数,此参数还没有值
2.实际参数(实参):在调用方法的时候给形参赋予的具体的值
```

<img src="img/1699414422241.png" alt="1699414422241" style="zoom:80%;" />

## 8.参数和返回值使用的时机

```java
1.参数:
  当想将方法A的数据传递到方法B时,那么定义方法B时就需要带个参数,在方法A中调用方法B时,可以将方法A中的数据通过参数传递到方法B中
      
2.返回值:
  调用方法A时,想要方法A的结果,去参与其他的操作,那么方法A就需要将自己的结果返回
```

<img src="img/1699427230425.png" alt="1699427230425" style="zoom:80%;" />

> 1.controller接收的请求参数需要一层一层传递到service层,service层需要将请求参数再传递到dao层
>
> 此时service的方法以及dao的方法都需要参数,去接收
>
> 2.dao层的结果需要传递给service,service再传递给controller层,此时dao层和service方法需要返回值

## 9.变量作为实参使用

```java
需求:定义一个方法,比较两个整数的大小,如果第一个比第二个大,返回true,否则返回false
```

```java
public class Demo07Method {
    public static void main(String[] args) {
        int i = 10;
        int j = 20;
        //传递的是i和j,但是我们真正传递的是i和j代表的数据,不是变量本身
        boolean result = compare(i, j);
        System.out.println("result = " + result);
    }
    public static boolean compare(int a,int b){
        if (a>b){
            return true;
        }else{
            return false;
        }
    }
}

package com.atguigu.helloworld;

import java.util.Random;
import java.util.Scanner;

public class Demo04Array {
    public static void main(String [] args) {
        boolean result = compare();
        System.out.println(result);

    }
    public static boolean compare() {
        Random random = new Random();
        int rd1 = random.nextInt(100+1);
        System.out.println(rd1);

        int rd2 = random.nextInt(100+1);

        System.out.println(rd2);

       return rd1>rd2;
    }

}

# 第二章.方法注意事项终极版

```java
1.方法不调用不执行
2.方法的执行顺序只和调用顺序有关
3.方法之间不能互相嵌套
    
4.void不能和[return 结果]共存,但是void能和[return]共存
  a.void:代表没有返回值
  b.return 结果:就代表有返回值了
               先将结果返回,然后结束方法
      
  c.return:仅仅代表结束方法,不代表有返回值
  
5.一个方法中不能连续写多个return(也就是说一个方法不能都多个返回值)
      
6.调用方法的时候要看看下面有没有这个方法,没有的方法直接调用会报错      
      
```

```java
public class Demo08Method {
    public static void main(String[] args) {
        method01();
        //method04();
    }

    public static int method01(){
        return 1;
    }
    public static void method02(){
        return;
    }

    public static int method03(){
        return 1;
        //return 2;
    }
}
```

> ```java
> 初学者怎么写:
>      1.先定义,再调用
>      2.如果是没有返回值的方法,直接在被调用的方法内部输出结果
>      3.如果是带返回值的方法,就调用完毕之后,用一个变量去接收结果,输出这个变量
>      4.调用方法:
>         直接调用:方法名() 或者 方法名(实参) -> 只针对于无返回值的方法
>         打印调用:sout(方法名()) 或者 sout(方法名(实参)) -> 针对有返回值的方法 -> 不推荐使用
>         赋值调用:数据类型 变量名 = 方法名() 或者 数据类型 变量名 = 方法名(实参) -> 针对于有返回值的方法 -> 推荐使用
> ```
>
> ```java
> 怎么练习:
>   1.如果定义的方法没有返回值,写个void 不要写return 结果
>   2.如果定义的方法有返回值,就将void改成具体的返回值类型,在 方法体中最后写一个return 结果,将结果返回
>   3.如果方法有返回值,调用的时候推荐使用赋值调用,如果没有返回值,使用直接调用
>   4.练习的时候,只需要完成一个简单的需求(比如两个整数相加),针对此需求,定义4种方法,并成功调用         
> ```

# 第三章.方法练习

## 1.方法练习1(判断奇偶性)

```java
需求:
   键盘录入一个整数,将整数传递到另外一个方法中,在此方法中判断这个整数的奇偶性
   如果是偶数,方法返回"偶数"  否则返回"奇数"

方法三要素:
  方法名:要
  参数:要
  返回值:要
```

```java
public class Demo01Method {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int data = sc.nextInt();
        String result = method(data);
        System.out.println("result = " + result);
    }
    /*
         键盘录入一个整数,将整数传递到另外一个方法中,在此方法中判断这个整数的奇偶性
         如果是偶数,方法返回"偶数"  否则返回"奇数"
     */

    public static String method(int data){
        if (data%2==0){
            return "偶数";
        }else{
            return "奇数";
        }
    }
}

```

## 2.方法练习2(1-100的和)

```java
需求 :  求出1-100的和,并将结果返回

方法名:要
参数:不要
返回值:要    
```

```java
public class Demo02Method {
    public static void main(String[] args) {
        int result = method();
        System.out.println("result = " + result);
    }

    public static int method() {
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            sum+=i;
        }
        return sum;
    }
}
```

## 3.方法练习3(不定次数打印)

```java
需求:
   定义一个方法,给这个方法传几,就让这个方法循环打印几次"我是一个有经验的JAVA开发工程师"

方法名:要
参数:要
返回值:不要
```

```java
public class Demo03Method {
    public static void main(String[] args) {
        method(3);
    }
    public static void method(int n){
        for (int i = 0; i < n; i++) {
            System.out.println("我是一个有经验的java开发工程师");
        }
    }
}
```

## 4.方法练习4(遍历数组)

```java
需求:
  在main方法中定义一个数组,将数组传递到另外一个方法中,在此方法中遍历数组
  
```

```java
public class Demo04Method {
    public static void main(String[] args) {
       int[] arr1 = {1,2,3};
       method(arr1);
    }

    /*
       调用method方法,传递的实参时int[]数组
       所以形参也应该用int型数组来接收
     */
    public static void method(int[] arr2){//int[] arr2 = arr1
        for (int i = 0; i < arr2.length; i++) {
            System.out.println(arr2[i]);
        }
    }

}
```

<img src="img/1699434078842.png" alt="1699434078842" style="zoom:80%;" />

> 数组本身是引用数据类型,引用数据类型做方法参数传递,传递的是地址值

## 5.练习7

```java
数组作为返回值返回
```

```java
public class Demo05Method {
    public static void main(String[] args) {
        int[] arr2 = method();//int[] arr2 = arr1
        for (int i = 0; i < arr2.length; i++) {
            System.out.println(arr2[i]);
        }
    }

    public static int[] method(){
        int a = 10;
        int b = 20;
        int sum = a+b;

        int sub = a-b;

        int[] arr1 = {sum,sub};
        return arr1;//返回的是一个int[],那么返回值类型也应该是int[]
    }
}

```

<img src="img/1699434588013.png" alt="1699434588013" style="zoom:80%;" />

> 返回值为引用数据类型时,返回的是地址值

# 第四章.方法的重载(Overload)

```java
需求:定义三个方法,分别求2个整数相加,3个整数相加,4个整数相加
```

```java
public class Demo1OverLoad {
    public static void main(String[] args) {
        sum(10,20);
        sum(10,20,30);
        sum(10,20,30,40);
    }

    //两个整数相加
    public static void sum(int a,int b){
        System.out.println(a+b);
    }

    //三个整数相加
    public static void sum(int a,int b,int c){
        System.out.println(a+b+c);
    }

    //四个整数相加
    public static void sum(int a,int b,int c,int d){
        System.out.println(a+b+c+d);
    }
}

```

```java
1.概述:方法名相同,参数列表不同的方法
2.什么叫参数列表不同:
  a.参数个数不同
  b.参数类型不同
  c.参数类型顺序不同
      
3.判断两个方法是否为重载方法,和什么无关:
  a.和参数名无关
  b.和返回值无关
```

```java
public static void open(){}
public static void open(int a){}
static void open(int a,int b){}
public static void open(double a,int b){}
public static void open(int a,double b){}
public void open(int i,double d){}
public static void OPEN(){}
public static void open(int i,int j){}
```

<img src="img/1699436053197.png" alt="1699436053197" style="zoom:80%;" />

```java
如果定义方法功能一样,只不过实现细节不一样,就可以考虑定义成重载的方法
```

# 模块七_面向对象

```java
模块六回顾:
  1.概述:拥有功能性代码的代码块
    将来干开发一个功能就应该对应一个方法
  2.方法的通用定义格式:
    修饰符 返回值类型 方法名(参数){
        方法体
        return 结果
    }

    a.修饰符:public static
    b.返回值类型:方法最终返回的结果的数据类型
    c.方法名:给方法取的名字,见名知意,小驼峰式
    d.参数:进入到方法内部参与执行的数据
    e.方法体:具体实现该方法的具体代码
    f.return 结果:该方法操作完参数之后,最终返回的一个数据
        
  3.无参无返回值方法:
    a.定义:
      public static void 方法名(){
          方法体
      }
    b.调用:方法名()
        
  4.有参无返回值方法:
    a.定义:
      public static void 方法名(形参){
          方法体
      }

    b.调用:
      方法名(实参)
          
  5.无参有返回值方法:
    a.定义:
      public static 返回值类型 方法名(){
          方法体
          return 结果
      }

    b.调用:
      数据类型 变量名 = 方法名()
          
  6.有参有返回值方法:
    a.定义:
      public static 返回值类型 方法名(形参){
          方法体
          return 结果
      }

    b.调用:
      数据类型 变量名 = 方法名(实参)
          
  7.注意事项:
    a.方法不调用不执行,main方法是jvm调用的
    b.方法之间不能互相嵌套
    c.方法的执行顺序只和调用顺序有关
    d.void不能和return 结果共存,但是能和return共存
      void:代表没有返回值
      return 结果:代表有返回值,先将结果返回,再结束方法
      return:仅仅代表结束方法
          
    e.一个方法中不能连续写多个return
    f.调用方法是,需要看有没有此方法
          
          
  8.参数和返回值使用时机:
    a.参数:当想将一个方法中的数据,传递到另外一个方法中操作,就需要参数了
    b.返回值:如果调用者需要使用被调用者的结果,被调用者就需要将自己的结果返回
        
        
  9.方法的重载:
    a.概述:方法名相同,参数列表不同
    b.什么叫参数列表不同:
      参数个数不同,类型不同,类型顺序不同
    c.和什么无关:
      和参数名无关,和返回值无关
    
模块七重点:
  1.知道为啥使用面向对象思想编程
  2.知道怎么使用面向对象思想编程
  3.知道什么时候使用面向对象思想编程
  4.会利用代码去描述世间万物的分类
  5.会在一个类中访问另外一个类中的成员 -> new对象
  6.成员变量和局部变量的区别
```

# 第一章.类和对象

## 1.面向对象的介绍

1.面向过程:自己的事情自己干,代表语言C语言
          洗衣服:每一步自己要亲力亲为 -> 找个盆,放点水,找个搓衣板,搓搓搓
2.面向对象:自己的事情别人帮忙去干,代表语言Java语言    
          洗衣服:自己的事情别人干 -> 全自动洗衣机
              
3.为啥要使用面向对象思想编程:懒
  很多功能别人都给我们实现好了,我们只需要直接拿过来使用即可,简化了我们自己的编写过程,减少了我们的代码量
    
4.什么时候使用面向对象思想编程:
  调用别人的功能时
  在一个类中想使用别的类中的成员时,就使用面向对象思想编程
  至于我们使用的功能人家怎么实现的,我们不需要关心,我们只需要知道怎么使用即可
      
5.怎么使用面向对象思想编程:
  a.new呀,new完点呀-> 点代表的是调用
  b.特殊:如果调用的成员带static关键字,我们不需要new,我们直接类名点即可

/**
 * Demo01Object类展示了如何使用面向对象的思想来使用其他类的方法。
 * 主要通过创建对象并调用对象中的方法来实现特定功能。
 */
public class Demo01Object {
    public static void main(String[] args) {
        /*使用Scanner类的next方法输入字符串
           我们想在Demo01Object类中使用Scanner类中的next方法实现录入字符串
           那么我们就需要使用面向对象思想编程

           对象:Scanner-> new出来的
           对象实现好的功能:next()

           我们只需要知道找来Scanner这个对象,就可以调用这个对象中实现好的next方法
           至于next方法怎么实现的,我们不需要关心
        */
        Scanner sc = new Scanner(System.in);
        String data = sc.next(); // 从标准输入读取一个单词
        System.out.println("data = " + data);

        System.out.println("===================================");

        /*使用Random类的nextInt方法生成随机整数
           我们想在Demo01Object类中使用Random类中的nextInt方法实现随机整数
           那么我们就需要使用面向对象思想编程

           对象:Random -> new出来的
           对象实现好的功能:nextInt()

           我们只需要知道找来Random这个对象,就可以调用Random中的nextInt方法
           至于nextInt怎么实现的,我们不需要关心
        */
        Random rd = new Random();
        int data2 = rd.nextInt(); // 生成一个范围内的随机整数
        System.out.println("data2 = " + data2);

        System.out.println("====================================");

        // 数组的简单使用
        int[] arr = {1, 2, 3, 4}; // 定义一个整型数组
        
        /*使用Arrays类的toString方法将数组转换为字符串输出
           Arrays就是我们找来的对象
           toStrig就是此对象中实现好的功能
           我们只需要调用,怎么实现我们不关心
        */
        System.out.println(Arrays.toString(arr));
    }
}
for-each循环语法 for (String[] row : table) 是一个for-each循环的声明。它的基本格式是:

   for (type element : collection) {
       // 循环体
   }
   

其中:
        type 是循环变量的类型,在本例中为 String【】,表示循环变量 row 是一个字符串数组。
        element 是循环变量的名称,在本例中为 row。每次循环时,row 将依次存储 table 中的每一个字符串数组。
        collection 是要遍历的数据结构,在本例中为 table,即待遍历的二维数组。
循环过程 在每次循环迭代中:
        row 被赋值为 table 中的下一个字符串数组(即下一行数据)。
        循环体内的代码被执行。此处的循环体是 System.out.println(Arrays.toString(row)),它将当前 row 的内容转化为字符串形式并打印出来。
        Arrays.toString(row) Arrays.toString() 是 java.util.Arrays 类的一个静态方法,它接收一个数组作为参数,并返回该数组内容的字符串表示。在本例中,它将当前 row(一个字符串数组)转化为形如 [element1, element2, ...] 的字符串,便于在控制台清晰地展示每一行的数据。
        综上所述,这段代码的作用是遍历二维数组 table,在每次循环中,将当前行(即一个字符串数组 row)通过 Arrays.toString() 转化为字符串并打印,从而实现对整个二维数组的逐行打印。执行这段代码后,控制台会输出.

## 2.类和对象

### 2.1类(实体类)_class

1.测试类:带main方法的类,主要是运行代码的
2.实体类:是一类事物的抽象表示形式
        世间万物的分类:比如: 人类   狗类   猫类   鼠标类

组成部分:
  1.属性(成员变量):这一类事物有啥
    a.定义位置:类中方法外  
    b.作用范围:作用于当前类
    c.定义格式: 数据类型 变量名
    d.默认值:
      整数:0
      小数:0.0
      字符:'\u0000'
      布尔:false
      引用:null
          
  2.行为(成员方法):这一类事物都能干啥
    只需要将模块六所学的方法中的static干掉,其他的都一样

```java

/**
 * Person类,用于表示一个人。
 */
public class Person {
    //属性-> 成员变量
    String name;
    int age;
    //行为 -> 成员方法
    public void eat(){
        System.out.println("人要干饭");
    }

    public void drink(){
        System.out.println("人要喝水");
    }
}
//描述动物类
public class Animal {
    String kind;// 动物的品种
    String color;// 动物的颜色

    //无参数,无返回值。
    public void eat(){
        System.out.println("动物要吃饭");
    }

    //无参数,无返回值。
    public void sleep(){
        System.out.println("动物都睡觉");
    }
}
//描述手机类

public class Phone {
    //属性
    String brand;

    String color;

    int price;
    //行为
    public void call(String name){
        System.out.println("给"+name+"打电话");
    }
    

    public String message(){
        return "给金莲发短信";
    }
}
### 2.2对象

1.概述:一类事物的具体体现
2.使用:
  a.导包: import 包名.类名
    如果两个类在同一个包下,想要使用对方的成员不需要导包
    如果两个类不在同一个包下,想要使用对方的成员需要导包
      
    特殊包:java.lang -> 使用lang包下的类不需要导包 -> String
        
    友情提示:在学四种权限修饰符之前,尽量让两个类在同一个包下
        
  b.创建对象:想要使用哪个类中的成员,就new哪个类的对象
    类名 对象名 = new 类名() -> 比如: Person person = new Person()
      
  c.调用成员(成员变量,成员方法) -> 想要使用哪个类中的成员,就用哪个类的对象去点哪个成员
    对象名.成员变量名 = 值
    对象名.方法名() -> 调用的是无参无返回值方法
    对象名.方法名(实参) -> 调用的是有参无返回值方法
    数据类型 变量名 = 对象名.方法名() -> 调用的是无参有返回值方法
    数据类型 变量名 = 对象名.方法名(实参) -> 调用的是有参有返回值方法

public class Person {
//属性-> 成员变量
    String name;
    int age;
//行为 -> 成员方法
    public void eat(){
        System.out.println("人要干饭");
    }

    public void drink(){
        System.out.println("人要喝水");
    }
}
public class Demo01Person {
    public static void main(String[] args) {

        Person person = new Person();

        System.out.println(person.name);
        System.out.println(person.age);

        person.name = "金莲";
        person.age = 26;

        System.out.println(person.name);
        System.out.println(person.age);

        person.eat();
        person.drink();
    }
}
### 3.练习

需求:用代码去描述一个手机类,在测试类中为手机类中的属性赋值,并且调用手机类中的功能

/**
 * 手机类
 * 用于描述手机的基本属性和功能
 */
public class Phone {
    // 手机品牌
    String brand;
    // 手机颜色
    String color;
    // 手机价格
    int price;

    /**
     * 打电话功能
     * @param name 接电话的人名
     * 说明:此方法用于模拟给指定的人打电话的操作
     */
    public void call(String name){
        System.out.println("给"+name+"打电话");
    }

    /**
     * 发短信功能
     * @return 返回短信内容
     * 说明:此方法用于模拟给金莲发短信的操作,返回预设的短信内容
     */
    public String message(){
        return "给金莲发短信";
    }
}

================================================================

/**
 * Demo02Phone类:演示手机的基本功能。
 */
public class Demo02Phone {
    public static void main(String[] args) {
        // 创建Phone实例
        Phone phone = new Phone();
        // 设置手机品牌、颜色和价格
        phone.brand = "苹果";
        phone.color = "黑色";
        phone.price = 7999;

        // 打印手机品牌、颜色和价格
        System.out.println(phone.brand);
        System.out.println(phone.color);
        System.out.println(phone.price);

        // 模拟给"金莲"打电话
        phone.call("金莲");
        // 获取并打印收到的短信
        String mess = phone.message();
        System.out.println(mess);
    }
}

## 3.匿名对象的使用

 1.int i = 10
   a.int:是数据类型
   b.i:变量名
   c.等号右边的10:真正的数据
       
 2.Person p = new Person()
   a.等号左边的Person:对象的类型,好比是int   
   b.p:对象名
   c.等号右边的new Person():真正的数据,是一个Person对象,将这个对象真正创建出来了    

1.所谓的匿名对象:其实就是没有等号左边的部分,只有等号右边的部分(对象)
2.使用:
  new 对象().成员
      
3.注意:
  a.如果我们只想单纯的调用一个方法,让方法执行,我们可以考虑使用匿名对象
  b.但是如果涉及到赋值,千万不要用匿名对象    

public class Person {

    String name;

    public void eat(){
        System.out.println("人要吃饭");
    }
}
public class Demo01Person {
    public static void main(String[] args) {
        // 原始方式创建和使用Person对象
        Person p = new Person();
        p.name = "金莲"; // 直接访问对象的属性
        System.out.println(p.name); // 输出对象的name属性值
        p.eat(); // 调用对象的方法

        System.out.println("=================");

        // 使用匿名对象的方式创建和使用Person对象
        new Person().eat(); // 创建匿名对象并调用其eat()方法

        new Person().name = "大郎"; // 为匿名对象设置name属性
        System.out.println(new Person().name); // 尝试输出新匿名对象的name属性值,但此时对象已失效,故输出null
    }
}

## 4.一个对象的内存图

## 5.两个对象的内存图

phone1和phone2都是new出来的,所以在堆内存中产生了两个不同的空间,所以改变一个空间的数据不会 影响另外一个空间中的数据

## 6.两个对象指向同一片空间内存图

phone2是phone1给的,phone1在内存中保存的是地址值,此时phone1和phone2地址值是一样的了,操作的是同一片空间的数据,所以改变一个对象的数据会影响到另外一个对象

# 第二章.成员变量和局部变量的区别

1.定义位置不同(重点)
  a.成员变量:类中方法外
  b.局部变量:定义在方法之中或者参数位置
      
2.初始化值不同(重点)
  a.成员变量:有默认值的,所以不用先手动赋值,就可以直接使用
  b.局部变量:是没有默认值的,所以需要先手动赋值,再使用
      
3.作用范围不同(重点)
  a.成员变量:作用于整个类
  b.局部变量:只作用于自己所在的方法,其他方法使用不了
      
4.内存位置不同(了解)
  a.成员变量:在堆中,跟着对象走
  b.局部变量:在栈中,跟着方法走

5.生命周期不同(了解)
  a.成员变量:随着对象的创建而产生,随着对象的消失而消失
  b.局部变量:随着方法的调用而产生,随着方法的调用完毕而消失    

成员变量和局部变量是Java编程语言中两种不同类型的变量,它们在声明的位置、作用域、生命周期、默认值以及访问权限等方面有着显著的区别。以下是两者详细对比:
成员变量:
声明位置:成员变量在类的内部定义,但不在任何方法或代码块内。它们可以位于类的顶部(直接在类名之后),也可以嵌套在其他成员(如方法、内部类等)之间。
作用域(可见性):成员变量在整个类的范围内都是可见的,包括类的所有方法和嵌套类。对于其他类,其可见性取决于访问修饰符(如public、private、protected、包访问权限等)。成员变量可以在类的实例间共享。
生命周期:成员变量与对象的生命周期紧密关联。当一个对象被创建时,其成员变量随之初始化;当对象被销毁(垃圾收集器回收)时,成员变量也随之消失。因此,成员变量的生命周期与具体对象绑定。
默认值:成员变量在定义后如果没有显式初始化,将根据其数据类型自动赋予默认值。例如,整型为0,浮点型为0.0,布尔型为false,引用类型为null。
内存分配:成员变量存储在堆内存中,作为对象的一部分。
访问控制:可以通过对象实例来访问成员变量,如 obj.memberVariable。也可以通过类的静态方法或非静态方法来访问(如果允许的话)。
局部变量:
声明位置:局部变量在方法、构造函数、代码块(如循环、条件语句等)内部声明。
作用域(可见性):局部变量的作用域局限于声明它的方法、构造函数或代码块内。一旦离开该作用域,局部变量将不可见且无法访问。
生命周期:局部变量在其所在的方法、构造函数或代码块被执行时创建,执行完毕后立即销毁。每次进入作用域都会创建一个新的局部变量实例,即使在同一个方法多次调用时也是如此。
默认值:局部变量没有默认值,声明后必须经过显式初始化才能使用,否则编译器会报错。
内存分配:局部变量存储在栈内存中,随着方法的调用和结束自动进行内存的分配与回收。
访问控制:局部变量只能在其声明的作用域内直接访问,不能通过对象或类进行访问。
总结起来,成员变量主要用于表示对象的状态,是对象的一部分,其生存期与对象相同,可以在对象间共享;而局部变量则是方法或代码块执行过程中的临时存储单元,仅在特定的执行上下文中存在,主要用于传递参数、保存中间结果等局部操作,且不能在方法外部直接访问。

public class Person {
    String name; // 成员变量

    public void eat(){
        int i = 10; // 局部变量,示例用途
        System.out.println(i); 

        // 输出成员变量name,成员变量可以直接使用,因为有默认值(null)
        System.out.println(name);
    }


    public void drink(){
        int j; // 声明局部变量j,但未赋值,因此需要赋值后才能使用

        // 输出成员变量name,演示即使在新的方法中,成员变量仍然可以直接访问
        System.out.println(name);

        // 局部变量i是在eat方法中定义的,在drink方法中无法直接访问。
    }
}

# 第三章.练习

需求:定义一个类MyDate,属性有 year  month  day     再定义一个类Citizen(公民类),属性有 name(String类型)  birthday(MyDate类型)  idCard(String),为这三个属性赋值,然后将值取出来

public  class MyDate {
        int year;
        int month;
        int day;
}
public class Citizen {
    String name;
    /*
    MyDate属于自定义类型(引用数据类型)
    这种类型要操作之前必须要赋值
    怎么赋值? 需要new对象赋值
    */
    MyDate birthday =  new MyDate();
    String idCard ;
}
public class Test {
    public static void main(String [] args) {
         Citizen citizen = new Citizen();
         citizen.name = "张三";
         citizen.idCard = "12324";
         /*
         citizen.birthday获取的是MyDate对象
         再去点year获取的是MyDate对象中的year
         链式调用
         */
         citizen.birthday.year = 1970;
         citizen.birthday.month = 1;
         citizen.birthday.day = 1;
        System.out.println(citizen.name);
        System.out.println(citizen.idCard);
        System.out.println(citizen.birthday.year);
    }
}

给引用数据类型赋值,需要new对象(String比较特殊,可以直接=赋值)

# 模块八_封装

模块七回顾:
  1.面向对象:是java的核心编程思想,自己的事情找对象帮我们去做
            有很多功能,别人帮我们实现好了,我们只需要找来这个对象,就可以调用这个对象中实现好的功能
    a.啥时候使用面向对象思想编程:在一个类中想访问另外一个类的成员(成员变量,成员方法)
    b.怎么使用:
      new对象 ,点成员
      特殊 :类名直接调用 -> 调用的成员中必须带static关键字
  2.类和对象:
    a.类:实体类
        属性(成员变量)  行为(成员方法,不带static的方法)
    b.对象:
      导包:两个类在同一个包下,使用对方的成员不需要导包,相反需要导包
          lang包下的类使用时不需要导包
      创建对象:想要使用哪个类中的成员,就new哪个类的对象
              类名 对象名 = new 类名()
      调用:想要使用哪个类的成员,就用哪个类的对象调用哪个成员
           对象名.成员
          
  3.匿名对象:没有等号左边的代码只有new
    a.注意:涉及到赋值,不要使用
  
  4.成员变量和局部变量的区别
    a.定义位置不同:
      成员:类中方法外
      局部:方法中或者参数位置
    b.初始化值不同
      成员:有默认值
      局部:没有默认值
    c.作用范围不同
      成员:作用于整个类
      局部:只作用于方法内部
    d.内存位置不同
      成员:在堆中,跟着对象走
      局部:在栈中,跟着方法走
    e.生命周期不同
      成员:随着对象的创建而创建,随着对象的消失而消失
      局部:随着方法的调用而产生,随着方法的调用完毕而消失
         

模块八重点:

  1.要会使用private关键字修饰成员,并知道被private修饰之后作用(访问特点)是什么
  2.会使用set方法为属性赋值,使用get方法获取属性值
  3.会利用this关键字区分重名的成员变量和局部变量
  4.会利用空参构造创建对象,并知道空参构造作用
  5.会使用有参构造创建对象,并为属性赋值
  6.会快速生成一个标准的javabean类

# 第一章.封装

将一个物品封装起来,外界不能直接使用了,提高了物品的安全性

## 1.封装的介绍以及使用

1.面向对象三大特征(OOP):  [封装]     继承    多态


2.什么是封装思想:
        a.我们找来了一个对象(洗衣机),只需要按一下按钮就可以了(使用洗衣机功能的过程就是在使用面向对象思想编程的过程),每一个按钮下面都包含了很多内部结构的细节(细节被封装到按钮里面了->封装),在使用的时候有必要了解洗衣机的内部构造吗?我们没有必要去了解内部结构,我们只知道调用就可以了
      
        所以,洗衣机来说,将细节隐藏起来了,细节我们不要关注,会对外提供了一个公共的接口(按钮),供我们人类使用  
      
        b.隐藏对象内部的复杂性,只对外提供公开,公共的接口,便于外界调用,从而提高了系统的可扩展性,可维护性,安全性,通俗来说,把该隐藏的隐藏起来(细节),把该暴露的暴露出来(对外提供的供别人使用的接口),这就是封装思想 
      
        我们只需要调用这个接口(功能)即可,此接口背后封装起来的细节就开始执行了,但是我们不需要关注细节,只关注公共的接口怎么调用
      
        c.将细节隐藏起来,不让外界随便使用,但是我们可以提供一个公共的接口让外界间接使用隐藏起来的细节->封装思想  

1.问题:
  定义成员变量,只要是new出来对象,就可以随便调用,随便赋值,哪怕是不合理的值我们也挡不住,怎么办?
  将属性封装起来(隐藏细节)
      
  a.关键字:private(私有化的) -> 被private修饰的成员只能在本类中使用,在别的类中使用不了
      
  b.注意:
    将代码放到一个方法中,也是封装的体现
    一个成员被private修饰也是封装的体现,只不过private最具代表性
        
  c.private的使用:
    修饰成员变量:private 数据类型 变量名
    修饰方法:将public改成private,其他的都一样
        
2.问题:属性被私有化了,外界直接调用不了了,那么此时属性就不能直接赋值取值了,所以需要提供公共的接口
       get/set方法
    
      set方法:为属性赋值
      get方法:获取属性值

get 和 set 是面向对象编程中的两个常见方法,它们通常成对出现,用于封装类的属性(也称为成员变量)。以下是 get 和 set 方法的主要区别:

get 方法(getter):
目的:提供访问(读取)对象内部某个私有属性(或称字段、变量)的值的方式。
命名约定:通常以 get 作为前缀,后面紧跟属性名,首字母大写。例如,对于一个名为 age 的属性,对应的 get 方法为 getAge()。
语法:

   public Type getPropertyName() {
       return propertyName;
   }

其中,Type 是属性的数据类型,propertyName 是需要访问的私有属性名。
作用:当外部代码(如其他类或方法)需要获取某个对象的属性值时,调用相应的 get 方法即可,而无需直接访问对象的私有属性,从而实现了数据的封装和隐藏,提高了代码的健壮性和安全性。

set 方法(setter):
目的:提供修改(设置)对象内部某个私有属性值的方式。
命名约定:同样以特定前缀 set 开头,后接属性名,首字母大写。比如,对于属性 age,对应的 set 方法为 setAge()。
语法:

   public void setPropertyName(Type value) {
       this.propertyName = value;
   }

这里的 Type 仍然是属性的数据类型,value 是传递给方法用来更新属性的新值。
作用:外部代码通过调用 set 方法来更改对象的属性值,而不是直接访问和修改对象的私有属性。这样做可以确保对属性值的修改遵循一定的规则(如数据验证、事件触发等),并且可以在不改变外部接口的情况下,灵活地调整内部属性的管理逻辑。
总结来说,get 和 set 方法是面向对象编程中实现封装性的关键手段,分别用于暴露(读取)和控制(修改)对象内部状态,同时隐藏了具体的实现细节,增强了代码的可维护性和扩展性。在实际应用中,这些方法常被称为属性的“访问器”(accessor)和“ mutator”(mutator)方法,或统称为“getter/setter”或“存取器”。

封装1是面向对象编程(Object-Oriented Programming, OOP)的三大核心特性之一(另外两个是继承和多态),旨在将数据(属性或成员变量)和操作数据的行为(方法)封装在一起,形成一个独立且可重用的单元——类。
基本概念:
隐藏内部细节:封装要求将类的内部实现细节(如数据成员和具体的实现逻辑)对外部世界(其他类或代码)隐藏起来。这通常通过访问修饰符(如Java中的private、protected、public等)来控制成员的可见性,确保外部代码只能通过类公开提供的接口(方法)与之交互,而不能直接访问或修改内部数据。
提供公共接口:为了允许外部代码访问和操作封装在类内部的数据,类通常会提供一组公共方法(如getter和setter方法)。这些方法构成了类的公共接口,外部代码可以通过调用这些方法来获取数据(getters)或设置数据(setters),而无需了解数据的具体存储方式或实现细节。
数据验证与一致性维护:通过封装,可以在类的内部对数据进行必要的验证(如检查输入的有效性、范围限制等)以及维护数据的一致性(如确保关联属性之间的约束关系)。这样,即使外部代码提供了错误的输入,也能确保类的状态始终保持正确。
优势与作用:
提高代码的模块化与复用性:封装使得代码组织成独立的、功能明确的模块(类),这些模块可以单独编写、测试和维护,易于复用在不同的场景中。
增强代码的安全性和稳定性:通过限制对数据的直接访问,封装可以防止外部代码意外修改或破坏对象状态,从而提高系统的稳定性和安全性。
简化系统设计与理解:对外部用户而言,只需关注类的公共接口,无需关心内部实现细节,降低了系统的复杂度,便于理解和使用。
支持未来的修改与扩展:当需要修改类的内部实现或增加新的功能时,只要保持公共接口不变,就不会影响到使用该类的现有代码。这符合“开闭原则”(Open-Closed Principle),即软件实体应当对扩展开放,对修改关闭。
总之,封装是通过隐藏对象的内部状态和实现细节,仅向外部暴露必要的接口来进行交互,以此实现代码的模块化、安全性和易维护性,是面向对象编程的基础和关键实践之一。

public class Person {
    private String name;
    private int age;

    //为name提供get/set方法
    public void setName(String xingMing) {
        name = xingMing;
    }

    public String getName() {
        return name;
    }

    //为age提供get/set方法
    public void setAge(int nianLing) {
        if (nianLing < 0 || nianLing > 150) {
            System.out.println("你脑子是不是秀逗啦!岁数不合理");
        } else {
            age = nianLing;
        }
    }

    public int getAge() {
        return age;
    }
}
/**
 * 测试类01,演示了Person类的简单使用。
 */
public class Test01 {
    /**
     * 主函数,创建一个Person实例并对其进行操作。
     * @param args 命令行参数,本例中未使用。
     */
    public static void main(String[] args) {
        // 创建Person实例
        Person person = new Person();
        
        // 通过setter方法设置person的属性
        person.setName("涛哥");
        person.setAge(18);

        // 通过getter方法获取person的属性值,并打印
        String name = person.getName();
        int age = person.getAge();
        System.out.println(name+"..."+age);
    }
}

 小结:
        用private将属性封装起来,外界不能直接调用,保护了属性
        对外提供一套公共的接口(set/get方法),让外界通过公共的接口间接使用封装起来的属性

## 2.this的介绍

1.如果成员变量和局部变量重名时,我们遵循"就近原则",先访问局部变量
2.this概述:代表的是当前对象
3.作用:this可以区分重名的成员变量和局部变量
      this点出来的一定是成员的变量
    
4.this代表当前对象,那么具体代表哪个对象呢?
  哪个对象调用的this所在的方法,this就代表哪个对象

public class Person {
    String name; // 人员的名称

    /*
     * @param name 调用此方法的外部传入的姓名。
     * 注:哪个对象调用的this所在的方法,this就代表哪个对象。
     */
    public void speak(String name) {
        System.out.println(this+"........"); // 输出当前Person对象的引用,展示“自我介绍”
        System.out.println(this.name+"您好,我是"+name); // 输出包含姓名的问候语
    }
}
/**
 * 测试类01
 * 主要演示了Person类的简单使用。
 */
public class Test01 {
    public static void main(String[] args) { // 程序入口
        // 创建第一个Person实例并进行操作
        Person person = new Person();
        System.out.println(person+"=========");
        person.name = "沉香"; // 设置名字为“沉香”
        person.speak("刘彦昌"); // 以“刘彦昌”为父进行发言

        System.out.println("=========="); // 分隔符

        // 创建第二个Person实例并进行操作
        Person person2 = new Person();
        System.out.println(person2+"+++++");
        person2.name = "奥特曼"; // 设置名字为“奥特曼”
        person2.speak("奥特曼之父"); // 以“奥特曼之父”为父进行发言
    }
}

/**
 * Person类用于创建人物实例,包含人物的姓名和年龄属性。
 */
public class Person {
    private String name;
    private int age;
    //为name提供get/set方法
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    //为age提供get/set方法
    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }
}
public class Test01 {
    public static void main(String[] args) {
        Person person = new Person();
        person.setName("涛哥");
        person.setAge(16);
        System.out.println(person.getName()+"..."+person.getAge());
    }
}

## 3.构造方法

1.概述:方法名和类名一致并且能初始化对象的方法
2.分类:
  a.无参构造:没有参数
  b.有参构造:有参数,参数是为指定的属性赋值

  c.满参构造:给所有属性赋值 
      
  以上构造咱们不用记那么详细,我们就记有参和无参构造就可以了
      
3.特点:
  a.方法名和类名一致
  b.没有返回值,连void都没有

### 3.1空参构造

1.格式:
  public 类名(){ 


  }
2.作用:
  new对象使用 
      
3.特点:
  每个类中默认都有一个无参构造,不写也有,jvm会自动提供
      

4.使用:一new对象就是在调用构造方法      

### 3.2有参构造

1.格式:
  public 类名(形参){
      为属性赋值
  }

2.作用:
  a.new对象
  b.为属性赋值
      
3.特点:
  jvm不会自动提供有参构造,但是将有参构造手写出来,jvm将不再提供无参构造,所以建议有参,无参的构造都手写上去

public class Person {
    private String name;
    private int age;

    /**
    * 无参构造函数,创建一个不带名字和年龄的Person实例。
    */
    public Person(){
        System.out.println("我是无参构造");
    }

    /**
    * 有参构造函数,创建一个具有指定名字和年龄的Person实例。
    * 
    * @param name 人的名字
    * @param age 人的年龄
    */
    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }

    /**
    * 设置人的名字。
    * 
    * @param name 要设置的名字
    */
    public void setName(String name) {
        this.name = name;
    }

    /**
    * 获取人的名字。
    * 
    * @return 当前人的名字
    */
    public String getName() {
        return name;
    }

    /**
    * 设置人的年龄。
    * 
    * @param age 要设置的年龄
    */
    public void setAge(int age) {
        this.age = age;
    }

    /**
    * 获取人的年龄。
    * 
    * @return 当前人的年龄
    */
    public int getAge() {
        return age;
    }
}
public class Test01 {
    /**
     * 程序的主入口函数。
     * @param args 命令行参数,本例中未使用。
     */
    public static void main(String[] args) {
        // 创建一个默认的Person对象
        Person person = new Person();

        // 创建一个具有姓名和年龄的Person对象,并打印其信息
        Person person2 = new Person("涛哥", 18);
        System.out.println(person2.getName()+"..."+person2.getAge());
    }
}

如何快速知道调用的成员是哪个类中的哪个成员呢?
按住ctrl不放,鼠标点击对应的成员 -> 会跳到对应的位置

## 4.标准JavaBean

JavaBean` 是 Java语言编写类的一种标准规范。符合`JavaBean` 的类,要求: 

(1)类必须是具体的(非抽象 abstract)和公共的,public class 类名

(2)并且具有无参数的构造方法,有参构造

(3)成员变量私有化,并提供用来操作成员变量的`set` 和`get` 方法。  


com.atguigu.controller -> 专门放和页面打交道的类(表现层)
com.atguigu.service -> 专门放业务处理的类 (业务层)
com.atguigu.dao -> 专门放和数据库打交道的类(持久层)
com.atguigu.pojo -> 专门放javabean类
com.atguigu.utils -> 专门放工具类

public class Person {
    // 个人姓名
    private String name;
    // 个人年龄
    private int age;

    /**
    * 无参构造函数,创建一个不带姓名和年龄的Person实例。
    */
    public Person(){
    }

    /**
    * 有参构造函数,创建一个具有指定姓名和年龄的Person实例。
    * 
    * @param name 个人姓名
    * @param age 个人年龄
    */
    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }

    /**
    * 设置个人姓名。
    * 
    * @param name 要设置的姓名
    */
    public void setName(String name) {
        this.name = name;
    }

    /**
    * 获取个人姓名。
    * 
    * @return 当前的姓名
    */
    public String getName() {
        return name;
    }

    /**
    * 设置个人年龄。
    * 
    * @param age 要设置的年龄
    */
    public void setAge(int age) {
        this.age = age;
    }

    /**
    * 获取个人年龄。
    * 
    * @return 当前的年龄
    */
    public int getAge() {
        return age;
    }
}
public class Test01 {
    /**
     * 程序的主入口函数
     * @param args 命令行参数
     */
    public static void main(String[] args) {
        // 创建一个Person实例,并设置其名字和年龄
        Person person = new Person();
        person.setName("金莲");
        person.setAge(26);
        // 打印Person实例的信息
        System.out.println(person.getName()+"..."+person.getAge());

        // 通过构造函数创建一个设置了名字和年龄的Person实例
        Person person2 = new Person("涛哥", 18);
        // 打印第二个Person实例的信息
        System.out.println(person2.getName()+"..."+person2.getAge());

    }
}

编写符合`JavaBean` 规范的类,以学生类为例,标准代码如下:

public class Student {
    // 学生的唯一标识符
    private int sid;
    // 学生的姓名
    private String sname;

    /**
     * 无参构造函数,创建一个空的学生对象。
     */
    public Student() {
    }

    /**
     * 带参数的构造函数,用于初始化学生对象。
     *
     * @param sid 学生的唯一标识符。
     * @param sname 学生的姓名。
     */
    public Student(int sid, String sname) {
        this.sid = sid;
        this.sname = sname;
    }

    /**
     * 获取学生的唯一标识符。
     *
     * @return 学生的唯一标识符。
     */
    public int getSid() {
        return sid;
    }

    /**
     * 设置学生的唯一标识符。
     *
     * @param sid 要设置的学生的唯一标识符。
     */
    public void setSid(int sid) {
        this.sid = sid;
    }

    /**
     * 获取学生的姓名。
     *
     * @return 学生的姓名。
     */
    public String getSname() {
        return sname;
    }

    /**
     * 设置学生的姓名。
     *
     * @param sname 要设置的学生的姓名。
     */
    public void setSname(String sname) {
        this.sname = sname;
    }
}

 快速生成标准javabean通用快捷键:alt+insert
1. 生成无参构造:

 2.生成有参构造

3.生成get/set方法:

/**
 * 测试类01,用于演示Student类的使用。
 */
public class Test01 {
    /**
     * 主函数,程序的入口点。
     * @param args 命令行参数,本程序未使用该参数。
     */
    public static void main(String[] args) {
        // 创建一个不带初始化参数的Student对象,并设置其ID和姓名
        Student s1 = new Student();
        s1.setSid(1);
        s1.setSname("涛哥");
        System.out.println(s1.getSid()+"..."+s1.getSname());

        // 输出分隔线
        System.out.println("==============");

        // 创建一个带初始化参数的Student对象,并直接打印其ID和姓名
        Student s2 = new Student(2, "金莲");
        System.out.println(s2.getSid()+"..."+s2.getSname());
    }
}

小结:

1.知道private的作用嘛?        私有的,别的类不能直接调用
2.知道空参构造作用嘛?        new对象
3.知道有参构造作用嘛?        new对象  为属性赋值
4.知道set方法作用嘛?           为属性赋值
5.知道get方法作用嘛?           获取属性值
6.知道this的作用嘛?              区分重名的成员变量和局部变量
7.知道快捷键生成标准javabean嘛? alt+insert

## 5.JavaBean怎么来的

1.将来的javabean都是和数据库的表相关联
  a.类名 -> 表名
  b.属性名 -> 列名
  c.对象 -> 表中每一行数据
  d.属性值 -> 表中单元格中的数据

将页面填写的数据获取到,封装到javabean中,一层一层传递到dao层,然后将javabean中的属性值获取出来放到表中保存 -> 相等于是一个添加功能

将所有的数据查询出来,封装成一个一个的javabean对象,然后将封装好的javabean对象放到一个容器中,将此容器返回 给页面,在页面上遍历展示

模块九_面向对象

模块八重点:
  1.封装:
    a.将细节隐藏起来,不让外界直接调用,再提供公共接口,供外界通过公共接口间接使用隐藏起来的细节
    b.代表性的:
      将一段代码放到一个方法中(隐藏细节),通过方法名(提供的公共接口)去调用
      private关键字 -> 私有的,被private修饰之后别的类不能直接调用,只能在当前类中使用
          
    c.get/set方法
      set方法:为属性赋值
      get方法:获取属性值
          
    d.this关键字:代表当前对象,哪个对象调用this所在的方法this就代表哪个对象
      区分重名的成员变量和局部变量
        
  2.构造:
    a.无参构造:new对象
      特点:jvm会自动为每个类提供一个无参构造
    b.有参构造:new对象  为属性赋值
      特点:如果手写了有参构造,jvm将不再提供无参构造,所以建议都写上
          
  3.标准javabean:
    a.类必须是公共的,具体的
    b.必须有私有属性
    c.必须有构造方法(无参,有参)
    d.必须有get/set方法
        
    快捷键:alt+insert
        
模块九重点:
  1.会定义静态成员以及会调用静态成员
  2.会使用可变参数(会给可变参数传参)
  3.会二分查找(手撕)
  4.会冒泡排序(手撕)
  5.会debug的使用    

第一章.static关键字

1.概述:static是一个静态关键字
2.使用:
   a.修饰一个成员变量:
     static 数据类型 变量名

   b.修饰一个方法:
      修饰符 static 返回值类型 方法名(形参){
             方法体
             return 结果
      }

3.调用静态成员:
   类名直接调用(不用new对象)

4.静态成员特点:
   a.静态成员属于类成员,不属于对象成员(非静态的成员属于对象成员)
   b.静态成员会随着类的加载而加载
   c.静态成员优先于非静态成员存在在内存中
   d.凡是根据静态成员所在的类创建出来的对象,都可以共享这个静态成员

/**
 * 学生类,用于表示一个学生的基本信息。
 */
public class Student {
    String name; // 学生姓名
    int age; // 学生年龄
    static String classRoom; // 学生所在班级,静态变量,适用于所有学生

}
public class Test01 {
    public static void main(String[] args) {
        //先给静态成员赋个值
        Student.classRoom = "222";

        Student s1 = new Student();
        s1.name = "郭靖";
        s1ge = 28;
        //s1.classRoom = "111";

        System.out.println(s1.name+","+s1.age+","+Student.classRoom);

        System.out.println("==============");

        Student s2 = new Student();
        s2.name = "黄蓉";
        s2.age = 26;
        //s2.classRoom = "111";

        System.out.println(s2.name+","+s2.age+","+Student.classRoom);
    }
}

2.static修饰成员的访问特点

1.在静态方法中能直接访问非静态成员嘛?  不能
  想要调用的话:new对象调用  
    
2.在非静态方法中能直接访问静态成员嘛? 能
  a.同类:
    直接调用
    类名调用
        
  b.不同类:
    类名调用
      
    
3.在静态方法中能直接访问静态成员嘛?能
  a.同类:
    直接调用
    类名调用
        
  b.不同类:
    类名调用
    
4.在非静态方法中能直接访问非静态成员嘛?能
  a.同类:
    直接调用
    new对象调用
        
  b.不同类:
    new对象调用

总结:

1.不管在不在同一个类中,非静态成员都可以new对象调用

2.不管在不在同一个类中,静态成员都可以类名调用

问题1:既然static成员那么好使(类名直接调用),那么我们在实际开发中,能不能将所有的成员都定义成静态的呢?
  不能

原因:由于静态成员会随着类的加载而加载,如果将所有的成员都变成静态的,那么类一加载,静态成员都会进内存,会大量占用内存空间

问题2:那么静态成员都啥时候定义呢?
  一般情况下,我们在抽取工具类的时候可以将工具类中的所有成员都定义成静态的

   

问题3:啥时候定义工具类?
   比如我们在写代码的过程中,发现有的功能在反复实现,代码一样,功能一样,此时就可以抽取出来,形成工具类

public class ArraysUtils {
 /*
    构造方法用private修饰

    工具类中的成员都是静态的,静态成员都是类名调用,不需要new对象
    所以工具类中的构造方法都是用private修饰

    如果构造方法被private修饰,那么在别的类中,就不能利用构造方法new对象
  */
 private ArraysUtils(){

 }


 //定义一个方法,实现获取int数组最大值
 public static int getMax(int[] arr){
     int max = arr[0];
     for (int i = 1; i < arr.length; i++) {
         if (max<arr[i]){
             max = arr[i];
         }
     }

     return max;
 }
}
public class Test01 {
 public static void main(String[] args) {
     int[] arr = {5,3,4,6,7,54,8};
     int max = ArraysUtils.getMax(arr);
     System.out.println("max = " + max);
 }
}
public class Test02 {
 public static void main(String[] args) {
     int[] arr = {5,4,5,7,8,9};
     int max = ArraysUtils.getMax(arr);
     System.out.println("max = " + max);
 }
}

第二章.可变参数

1.需求:
  定义一个方法,实现n个整数相加
      
2.分析:
  方法参数位置,只明确了参数的类型,但是不明确参数个数,此时就可以定义成可变参数

1介绍和基本使用

1.定义格式:
  数据类型...变量名
      
2.注意:
  a.可变参数的本质是一个数组
  b.参数位置不能连续写多个可变参数,而且当可变参数和其他普通参数一起使用时,可变参数需要放到参数列表最后   

public class Demo01Var {
    public static void main(String[] args) {
        sum(1,2,3,4,5);
        sum1(1,1,2,3,4);
    }

    public static void sum(int...arr){
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum+=arr[i];
        }
        System.out.println(sum);
    }
    
    public static void sum1(int i,int...arr){
        
    }
    
}

1.1字符串拼接

需求一:返回n个字符串拼接结果,如果没有传入字符串,那么返回空字符串""

public class Demo02Var {
    public static void main(String[] args) {
        String result = concat("张无忌", "张翠山", "张三丰", "张三");
        System.out.println("result = " + result);
    }

    public static String concat(String...s){
        String str = "";
        for (int i = 0; i < s.length; i++) {
            str+=s[i];
        }

        return str;
    }
}

需求二:n个字符串进行拼接,每一个字符串之间使用某字符进行分隔,如果没有传入字符串,那么返回空字符串""

比如:concat("-","张三丰","张翠山","张无忌") -> 返回 -> 张三丰-张翠山-张无忌

public class Demo03Var {
    public static void main(String[] args) {
        String result = concat("-", "张三丰", "张翠山", "张无忌");
        System.out.println("result = " + result);
    }

    public static String concat(String regex, String... s) {
        String str = "";
        for (int i = 0; i < s.length; i++) {
            if (i == s.length - 1) {
                str += s[i];
            } else {
                str += s[i] + regex;
            }
        }

        return str;
    }
}

第三章.递归

1.概述:方法内部自己调用自己
2.分类:
  a.直接递归
    public static void method(){
      method()
    }

 b.间接递归:
   A(){
       B()
   }
   B(){
       C()
   }
   C(){
       A()
   }

3.注意:
  a.递归必须要有出口,否则会出现"栈内存溢出"
  b.递归即使有出口,递归次数不不要太多    

public class Demo01Recursion {
    public static void main(String[] args) {
        method();
    }
    public static void method(){
        method();
    }
}

示例一:需求:利用递归输出3到1

public class Demo02Recursion {
    public static void main(String[] args) {
        method(3);
    }

    public static void method(int n){
        if (n==1){
            System.out.println(n);
            //结束方法
            return;
        }
        System.out.println(n);
        n--;
        method(n);
    }
}

示例二:求n!(n的阶乘)

1.需求:定义一个方法,完成3的阶乘
      3*2*1
2.分析:假如定义一个方法,代表n的阶乘 -> method(n) -> n接收几,就代表几的阶乘
  
  method(1)  1
  method(2)  2*1 -> 2*method(1)
  method(3)  3*2*1 -> 3*method(2)
    
  method(n) -> n*method(n-1)

public class Demo03Recursion {
    public static void main(String[] args) {
        int method = method(3);
        System.out.println("method = " + method);
    }

    public static int method(int n){
       if (n==1){
           return 1;
       }
       return n*method(n-1);
    }
}

示例三:计算斐波那契数列(Fibonacci)的第n个值

不死神兔
故事得从西元1202年说起,话说有一位意大利青年,名叫斐波那契。
在他的一部著作中提出了一个有趣的问题:假设一对刚出生的小兔一个月后就能长成大兔,再过一个月就能生下一对小兔,并且此后每个月都生一对小兔,一年内没有发生死亡
问:一对刚出生的兔子,一年内繁殖成多少对兔子? 

规律:一个数等于前两个数之和,比如: 1 1 2 3 5 8 13 21 34 55....

1.假设:定义一个方法,叫做method,参数传递month,代表月份
    
2.分析:
  method(1)     1
  method(2)     1
  method(3)     2 -> method(1)+method(2)
  method(4)     3 -> method(2)+method(3)
  method(5)     5 -> method(3)+method(4)   
      
  method(n) -> method(n-2)+method(n-1)
public class Demo04Recursion {
    public static void main(String[] args) {
        int method = method(12);
        System.out.println("method = " + method);
    }
​
    public static int method(int n){
       if (n==1 || n==2){
           return 1;
       }
       return method(n-1)+method(n-2);
    }
}

第四章.数组常见算法

1.数组翻转

1.概述:数组对称索引位置上的元素互换

public class Demo01Reverse {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7};
        for (int min = 0,max = arr.length-1;min<max;min++,max--){
            int temp = arr[min];
            arr[min] = arr[max];
            arr[max] = temp;
        }
​
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }
}

2.冒泡排序

 数组的排序,是将数组中的元素按照大小进行排序,默认都是以升序的形式进行排序,数组排序的方法很多,我们讲解的是数组的冒泡排序。
​
  排序,都要进行数组 元素大小的比较,再进行位置的交换。冒泡排序法是采用数组中相邻元素进行比较换位。
  arr[i](前一个元素)   arr[i+1](后一个元素)

2.1 代码实现

public class Demo02Bubble {
    public static void main(String[] args) {
        //定义一个数组,长度为5,最大索引为4
        int[] arr = {5,4,3,2,1};
​
        /*
           第一圈
             越界原因:当i变化到4的时候-> arr[4]>arr[5] -> 直接操作了5索引,所以越界了
             越界解决:我们可以让arr.length-1
                     如果arr.length-1-> 比较就是i<4 -> 此时i最大可以变化到3
                     当i变化到3时 -> arr[3]>arr[4] -> 正好是最后两个元素进行比较
         */
        /*for (int i = 0; i < arr.length-1-0; i++) {
            if (arr[i]>arr[i+1]){
                int temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }*/
​
        //第二圈
        /*for (int i = 0; i < arr.length-1-1; i++) {
            if (arr[i]>arr[i+1]){
                int temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }*/
​
        //第三圈
        /*for (int i = 0; i < arr.length-1-2; i++) {
            if (arr[i]>arr[i+1]){
                int temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }*/
​
        //第四圈
        /*for (int i = 0; i < arr.length-1-3; i++) {
            if (arr[i]>arr[i+1]){
                int temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }*/
​
​
        /*
           外层循环代表比较了几圈
           n-1圈
         */
        for (int j = 0; j < arr.length-1; j++) {
            /*
              内层循环代表每一圈比较的次数
              每圈都少比较一次
             */
            for (int i = 0; i < arr.length-1-j; i++) {
                if (arr[i]>arr[i+1]){
                    int temp = arr[i];
                    arr[i] = arr[i+1];
                    arr[i+1] = temp;
                }
            }
        }
​
​
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }
}
​

3.二分查找

1.前提:数组中的数据必须是有序的
2.查询思想:
  a.老式查询:遍历数组,一个一个比较 -> 查询效率慢
  b.二分查找:每次找中间索引对应的元素进行比较查询(每一次查询少一半数据)

public class Demo03Binary {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7,8,9};
        int index = binary(arr, 60);
        System.out.println(index);
    }
​
    public static int binary(int[] arr,int data){
        //定义三个变量,分别代表最大索引,最小索引,中间索引
        int min = 0;
        int max = arr.length-1;
        int mid = 0;
        //查找
        while(min<=max){
            mid = (min+max)/2;
            if (data>arr[mid]){
                min = mid+1;
            }else if(data<arr[mid]){
                max = mid-1;
            }else{
                return mid;
            }
        }
​
        return -1;
    }
}

第五章.对象数组

1.对象数组

1.需求:定义一个长度为3的数组,存储3个Person对象,遍历数组,将三个Person对象中的属性值获取出来
public class Person {
    private String name;
    private int age;
​
    public Person() {
    }
​
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    public int getAge() {
        return age;
    }
​
    public void setAge(int age) {
        this.age = age;
    }
}
​
public class Demo01ObjectArray {
    public static void main(String[] args) {
        /*
           Person p = new Person();
​
           1.定义一个存储int型数据的数组:int[]
           2.定义一个存储double型的数组:double[]
           3.定义一个存储String型的数组:String[]
           4.定义一个存储Person型的数组:Person[]
         */
        //定义数组
        Person[] arr = new Person[3];
​
        //创建三个对象
        Person p1 = new Person("金莲",26);
        Person p2 = new Person("涛哥",18);
        Person p3 = new Person("张三",20);
​
        //将三个对象保存到数组中
        arr[0] = p1;
        arr[1] = p2;
        arr[2] = p3;
​
        /*
           遍历
           当i = 0  arr[0] 就是 p1对象
           当i = 1  arr[1] 就是 p2对象
           当i = 2  arr[2] 就是 p3对象
         */
        for (int i = 0; i < arr.length; i++) {
            //Person p = arr[i];
            System.out.println(arr[i].getName()+"..."+arr[i].getAge());
        }
    }
}
​

练习1

(1)定义学生类Student
​
    声明姓名和成绩成员变量
​
(2)测试类ObjectArrayTest的main中创建一个可以装3个学生对象的数组,并且按照学生成绩排序,显示学生信息
public class Student {
    private String name;
    private int score;
​
    public Student() {
    }
​
    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    public int getScore() {
        return score;
    }
​
    public void setScore(int score) {
        this.score = score;
    }
}
​
public class Demo02ObjectArray {
    public static void main(String[] args) {
        Student[] students = new Student[3];
        students[0] = new Student("金莲",26);
        students[1] = new Student("大郎",50);
        students[2] = new Student("涛哥",18);
​
        for (int j = 0; j < students.length-1; j++) {
            for (int i = 0; i < students.length-1-j; i++) {
                if (students[i].getScore()>students[i+1].getScore()){
                    Student temp = students[i];
                    students[i] = students[i+1];
                    students[i+1] = temp;
                }
            }
        }
​
        for (int i = 0; i < students.length; i++) {
            System.out.println(students[i].getName()+"..."+students[i].getScore());
        }
    }
}
​

第六章.方法参数

1.基本数据类型做方法参数传递

基本类型做方法参数传递,传递的是值,不是变量本身
方法运行:压栈
方法运行完毕:弹栈 -> 释放栈内存
public class Demo01Param {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        method(a,b);
        System.out.println(a);//10
        System.out.println(b);//20
    }
    public static void method(int a,int b){
        a+=10;
        b+=20;
        System.out.println(a);//20
        System.out.println(b);//40
    }
}
​

2.引用数据类型做方法参数传递

引用数据类型做方法参数传递时,传递的是地址值
public class Demo02Param {
    public static void main(String[] args) {
        int[] arr = {10,20};
        method(arr);
        System.out.println(arr[0]);//20
        System.out.println(arr[1]);//40
    }
​
    public static void method(int[] arr){
        arr[0]+=10;
        arr[1]+=20;
        System.out.println(arr[0]);//20
        System.out.println(arr[1]);//40
    }
}

第七章.命令行参数(了解)

通过命令行给main方法的形参传递的实参称为命令行参数

public class TestCommandParam{
    //形参:String[] args
    public static void main(String[] args){
        for(int i=0; i<args.length; i++){
            System.out.println("第" + (i+1) + "个参数的值是:" + args[i]);
        }
    }
}

运行命令:

java TestCommandParam
java TestCommandParam 1 2 3
java TestCommandParam hello atguigu

第八章.其他操作

1.快速生成方法

1.初学者要求先定义,再调用;不是初学者,就可以先调用,再定义方法
  a.快捷键:alt+回车
      
2.快速将一段代码抽取到一个方法中:
  a.选中要抽取的方法
  b.按ctrl+alt+m      

2.debug调试

1.概述:调试代码的一种手段
    
2.作用:
  a.能清楚的看到每个变量在代码执行过程中的变化
  b.找错
      
3.使用:
  a.在想要开始debug的那一行左边点击一下,出现红色小圆点(断点)
  b.右键-> 点击debug    

模块十_面向对象

模块十重点:
  1.知道继承的好处
  2.会使用继承
  3.知道继承之后成员变量以及成员方法的访问特点
  4.会方法的重写,以及知道方法重写的使用场景
  5.会使用this关键字调用当前对象中的成员
  6.会使用super关键字调用父类中的成员
  7.会定义抽象方法以及抽象类
  8.会重写抽象方法

第一章.继承

1.什么是继承

1.父类怎么形成的:我们的定义了多个类,发现这些类中有很多重复性的代码,我们就定义了一个父类,将相同的代码抽取出来放到父类中,其他的类直接继承这个父类,就可以直接使用父类中的内容了
​
2.怎么去继承: extends
   子类 extends 父类
​
3.注意:
  a.子类可以继承父类中私有和非私有成员,但是不能使用父类中私有成员
  
  b.构造方法不能继承
​
4.继承怎么学:
   a.继承不要从是否"拥有"方面来学习
      要从是否能"使用"方面来学习

2.继承如何使用

1.定义一个父类,在其中定义重复性的代码
2.定义一个子类继承父类 -> extends
  子类 extends 父类
3.创建子类对象,直接使用父类中非私有成员    
public class Employee {
    String name;
    int age;
​
    public void work(){
        System.out.println("工作");
    }
​
    private void eat(){
        System.out.println("员工要干饭");
    }
}
public class Test01 {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        teacher.name = "涛哥";
        teacher.age = 18;
        System.out.println(teacher.name+"..."+teacher.age);
        teacher.work();
        //teacher.eat();子类继承父类之后不能使用父类私有成员,只能使用父类非私有成员
​
        System.out.println("============");
​
        Manager manager = new Manager();
        manager.name = "金莲";
        manager.age = 18;
        System.out.println(manager.name+"..."+manager.age);
        manager.work();
    }
}

​3.继承中,成员变量和成员方法的访问特点

3.1 成员变量
3.1.1 子类和父类中的成员变量不重名:
public class Fu {
    int numFu = 100;
}
​
public class Zi extends Fu{
    int numZi = 10;
}
public class Test01 {
    public static void main(String[] args) {
        //创建父类对象
        Fu fu = new Fu();
        System.out.println(fu.numFu);//父类中的numFu
        //System.out.println(fu.numZi);//不能直接调用子类特有的成员

        System.out.println("=================");
        //创建子类对象
        Zi zi = new Zi();
        System.out.println(zi.numZi);
        System.out.println(zi.numFu);//继承了父类,可以使用父类中非私有成员
    }
}
总结:看等号左边是谁,先调用谁中的成员  
    如果等号左边是父类类型,只能调用父类中的成员变量,如果等号左边是子类类型,既能调用子类的,还能调用父类中继承过来的非私有成员
2.1.2.子类和父类中的成员变量重名
public class Fu {
    int numFu = 100;

    int num = 10000;
}
public class Zi extends Fu{
    int numZi = 10;

    int num = 1000;
}
public class Test01 {
    public static void main(String[] args) {
        //创建父类对象
        Fu fu = new Fu();
        System.out.println(fu.numFu);//父类中的numFu
        //System.out.println(fu.numZi);//不能直接调用子类特有的成员
        System.out.println(fu.num);//父类的

        System.out.println("=================");
        //创建子类对象
        Zi zi = new Zi();
        System.out.println(zi.numZi);
        System.out.println(zi.numFu);//继承了父类,可以使用父类中非私有成员
        System.out.println(zi.num);//子类的
    }
}

总结:继承前提下,成员变量访问特点口诀:

看等号左边是谁,先调用谁中的成员,子类没有,找父类

2.2 成员方法

public class Fu {
    public void methodFu(){
        System.out.println("我是父类中的methodFu");
    }

    public void method(){
        System.out.println("我是父类中的method方法");
    }
}
public class Zi extends Fu{
    public void methodZi(){
        System.out.println("我是子类中的methodZi方法");
    }

    public void method(){
        System.out.println("我是子类中的method方法");
    }
}
public class Test01 {
    public static void main(String[] args) {
        Fu fu = new Fu();
        fu.methodFu();
       // fu.methodZi(); 不能直接调用子类特有的方法
        fu.method();//父类中的method方法

        System.out.println("=====================");
        Zi zi = new Zi();
        zi.methodZi();
        zi.methodFu();//继承父类之后,能调用父类非私有成员
        zi.method();//子类中的method方法

        System.out.println("===================");

        Fu fu1 = new Zi();
        fu1.method();//调用的是子类中的method方法
    }
}

成员方法:看new的是谁,先调用谁中的方法,子类没有,找父类

继承中,成员变量访问特点:看等号左边是谁,先调用谁中的成员变量

成员方法访问特点:看new的是谁,先调用谁中的方法

4.方法的重写

1.概述:子类中有一个和父类方法名以及参数列表相同的方法
2.前提:继承
3.访问:看new的是谁,先调用谁中的,如果new的是子类,调用调用子类重写的方法,子类没有,找父类
4.检测是否为重写方法:在该方法上写
  @Override  
public class Fu {
    public void methodFu(){
        System.out.println("我是父类中的methodFu方法");
    }
    public void method(){
        System.out.println("我是父类中的method方法");
    }
}
public class Zi extends Fu{
    public void methodZi(){
        System.out.println("我是子类中的methodZi方法");
    }

    @Override
    public void method(){
        System.out.println("我是子类中的method方法");
    }
public class Test01 {
    public static void main(String[] args) {
        Fu fu = new Fu();
        fu.methodFu();//自己的methodFu方法
        fu.method();//new的是父类对象,那么调用的就是父类中的method

        System.out.println("================");

        Zi zi = new Zi();
        zi.methodZi();
        zi.methodFu();
        zi.method();//子类中的method方法
    }
}

4.1.注意事项

1.子类重写父类方法之后,权限必须要保证大于等于父类权限(权限指的是访问权限)
  public -> protected -> 默认 -> private
2.子类方法重写父类方法,方法名和参数列表要一样
3.私有方法不能被重写,构造方法不能被重写,静态方法不能被重写
4.子类重写父类方法之后,返回值类型应该是父类方法返回值类型的子类类型    
public class Fu {
    public void methodFu(){
        System.out.println("我是父类中的methodFu方法");
    }
    public void method(){
        System.out.println("我是父类中的method方法");
    }

    void method01(){

    }

   /* public static void method02(){

    }*/

    public Fu method03(){
        return null;
    }
}
public class Zi extends Fu{
    public void methodZi(){
        System.out.println("我是子类中的methodZi方法");
    }

    @Override
    public void method(){
        System.out.println("我是子类中的method方法");
    }

    @Override
   public void method01(){

    }

   /* public static void method02(){

    }*/

    @Override
    public Zi method03(){
      return null;
    }
}

4.2.使用场景

1.使用场景:功能升级改造,子类需要对父类中已经实现好的功能进行重新改造

1702892890941

public class OldPhone {
    public void call(){
        System.out.println("打电话");
    }

    public void message(){
        System.out.println("发短信");
    }

    public void show(){
        System.out.println("显示手机号");
    }
}
public class NewPhone extends OldPhone{
    public void show(){
        System.out.println("显示手机号");
        System.out.println("显示归属地");
    }
}
public class Test01 {
    public static void main(String[] args) {
        NewPhone newPhone = new NewPhone();
        newPhone.call();
        newPhone.message();
        newPhone.show();
    }
}

第二章.super和this

1.继承中构造方法的特点

1.注意:new子类对象时,会先初始化父类(先走父类无参构造方法)
2.原因:
  每个构造方法的第一行,默认都会有一个super(),不写jvm自动提供一个
  super()代表的是父类无参构造      
public class Fu {
    public Fu(){
        System.out.println("我是父类中的无参构造");
    }
}
public class Zi extends Fu{
    public Zi(){
        //super();
        System.out.println("我是子类中的无参构造");
    }

    public Zi(int i){
        //super();
        System.out.println("我是子类中的有参构造");
    }
}
public class Test {
    public static void main(String[] args) {
        Zi zi = new Zi();
        System.out.println("===========");
        Zi zi1 = new Zi(10);
    }
}

2.super和this的具体使用

2.1 super的具体使用

1.概述:代表的是父类引用
2.作用:可以调用父类中的成员
3.使用:
  a.调用父类构造方法-> 在子类中的构造中写
    super() -> 调用父类无参构造
    super(实参)  -> 调用父类有参构造
      
  b.调用父类成员变量:
    super.成员变量名
        
  c.调用父类成员方法:
    super.成员方法名(实参)
public class Fu {
    int num = 10;
    public Fu(){
        System.out.println("我是父类中的无参构造");
    }

    public Fu(int data){
        System.out.println("我是父类中的有参构造");
    }

    public void method(){
        System.out.println("我是父类中的method方法");
    }
}
public class Zi extends Fu{
    int num = 100;
    public Zi(){
        super();//调用父类中的无参构造
        System.out.println("我是子类中的无参构造");
    }

    public Zi(int num){
        super(10);//调用父类的有参构造
        System.out.println("我是子类中的有参构造");
    }

    public void method(){
        super.method();//调用父类的method方法
        System.out.println("我是子类中的method方法");
        System.out.println(num);//子类自己的
        System.out.println(super.num);//调用父类的num
    }
}
public class Test01 {
    public static void main(String[] args) {
        Zi zi = new Zi();
        System.out.println("============");
        Zi zi1 = new Zi(10);
        System.out.println("============");
        Zi zi2 = new Zi();
        zi2.method();

    }
}

2.2 this的具体使用

1.this概述:代表的是当前对象(哪个对象调用的this所在的方法,this就代表哪个对象)
2.作用:
  a.区分重名的成员变量和局部变量
  b.调用当前对象中的成员
3.使用:
  a.调用当前对象的构造:在构造中写
    this():调用当前对象的无参构造
    this(实参):调用当前对象的有参构造
  b.调用当前对象的成员变量:
    this.成员变量名
  c.调用当前对象的成员方法:
    this.成员方法名(实参)
4.注意:
  不管是super还是this,只要在构造中使用,都必须在第一行,所以二者不能同时手写出来
public class Person {
    int num = 10;
    public Person(){
        //this(10);
        System.out.println("我是Person中的无参构造");
    }

    public Person(int data){
        //super();super和this不能同时再构造中出现
        this();
        System.out.println("我是Person中的有参构造");
    }

    public void method(){
        int num = 20;
        System.out.println(num);//20
        System.out.println(this.num);//10
        this.method01();
        System.out.println("我是Person类中的method方法");
    }

    public void method01(){
        System.out.println("我是Person类中的method01方法");
    }
}
public class Test01 {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println("========");
        Person person1 = new Person(10);
        System.out.println("========");
        Person person2 = new Person();
        person2.method();
    }
}

3.继承的特点

1.继承只支持单继承,不能多继承
  public class A extends B,C{}  -> 错误
2.继承支持多层继承
  public class A extends B{}
  public class B extends C{}
3.一个父类可以有多个子类
  public class A extends C{}
  public class B extends C{}

4.构造方法不能继承,也不能重写
  私有方法可以继承,但是不能被重写
  静态方法可以继承,但是不能被重写
public class Fu {
    public void method01(){
        System.out.println("method01方法");
    }

    private void method02(){
        System.out.println("method02方法");
    }

    public static void method03(){
        System.out.println("method03方法");
    }
}
public class Zi extends Fu{
    @Override
    public void method01(){
        System.out.println("重写的method01方法");
    }

/*    @Override
    private void method02(){
        System.out.println("method02方法");
    }*/
}
public class Test01 {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.method03();
        Zi.method03();
    }
}

4.问题:如何为父类中private的成员变量赋值(经验值)

4.1.利用set赋值

public class Employee {
    private String name;
    private int age;

    public Employee() {
    }

    public Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void work(){
        System.out.println("工作");
    }
}
public class Teacher extends Employee{
}
        Teacher teacher = new Teacher();
        teacher.setName("涛哥");
        teacher.setAge(18);
        System.out.println(teacher.getName()+"..."+teacher.getAge());

4.2.利用构造方法赋值

public class Employee {
    private String name;
    private int age;

    public Employee() {
    }

    public Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void work(){
        System.out.println("工作");
    }
}
public class Manager extends Employee{
    public Manager() {
    }

    public Manager(String name, int age) {
        super(name, age);
    }
}
        Manager manager = new Manager("金莲", 24);
        System.out.println(manager.getName()+"..."+manager.getAge());

1702979683186

第三章.抽象

1.抽象的介绍

   1.抽象类怎么来的?
     抽取共性方法,放到父类中,发现方法没法实现,因为每个子类对此方法的实现方式细节不一样
此时方法体说不清道不明,可以定义成抽象方法
    抽象方法所在的类一定是抽象类


   2.关键字: abstract

   3.抽象方法:
      修饰符 abstract 返回值类型 方法名(参数);

   4.抽象类:
       public  abstract class 类名{}

   5.注意:
       a.抽象方法所在的类一定是抽象类
       b.抽象类中不一定非得有抽象方法
       c.子类继承父类之后,需要重写父类
          中所有的抽象方法,不然编译报错
       d.抽象类不能new对象,只能通过new子类对象调动重写方法
           
   6.可以将抽象类看成是一类事物的标准,要求只要是属于这一类的,都必须要拥有抽象类中的方法,必须要给我实现,怎么证明拥有了,怎么证明实现了呢?-> 重写
     至于这个方法怎么实现,就看子类重写之后怎么写方法体了
public abstract class Animal {
   public abstract void eat();
   public abstract void drink();
}
public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗啃骨头");
    }

    @Override
    public void drink() {
        System.out.println("狗喝水");
    }
}
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    @Override
    public void drink() {
        System.out.println("猫喝水");
    }
}
public class Test01 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();
        dog.drink();
        System.out.println("===================");
        Cat cat = new Cat();
        cat.eat();
        cat.drink();
    }
}

2.抽象的注意事项

1.抽象类不能直接new对象,只能创建非抽象子类的对象
2.抽象类中不一定非得有抽象方法,但是抽象方法所在的类一定抽象类
3.抽象类的子类,必须重写父类中的所有抽象方法,否则,编译报错,除非该子类也是抽象类
4.抽象类中可以有成员变量,构造,成员方法
5.抽象类中可以有构造方法,是供子类创建对象时,初始化父类属性使用的    
public abstract class Employee {
    private String name;
    private int age;

    public Employee() {
    }

    public Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public abstract void work();
}
public class Teacher extends Employee{
    public Teacher() {
    }

    public Teacher(String name, int age) {
        super(name, age);
    }

    @Override
    public void work() {
        System.out.println("涛哥在讲java");
    }
}
public class Test01 {
    public static void main(String[] args) {
        Teacher t1 = new Teacher("涛哥", 18);
        System.out.println(t1.getName()+"..."+t1.getAge());
    }
}

第四章.综合案例

某IT公司有多名员工,按照员工负责的工作不同,进行了部门的划分(研发部、维护部)。
研发部(Developer)根据所需研发的内容不同,又分为 JavaEE工程师 、Android工程师 ;
维护部(Maintainer)根据所需维护的内容不同,又分为 网络维护工程师(Network) 、硬件维护工程师(Hardware) 。

公司的每名员工都有他们自己的员工编号、姓名,并要做它们所负责的工作。

工作内容:

- JavaEE工程师: 员工号为xxx的 xxx员工,正在研发电商网站
- Android工程师:员工号为xxx的 xxx员工,正在研发电商的手机客户端软件
- 网络维护工程师:员工号为xxx的 xxx员工,正在检查网络是否畅通
- 硬件维护工程师:员工号为xxx的 xxx员工,正在修复电脑主板

请根据描述,完成员工体系中所有类的定义,并指定类之间的继承关系。进行XX工程师类的对象创建,完成工作方法的调用。

方式1:利用set赋值

public abstract class Employee {
    private int id;
    private String name;

    public Employee() {
    }

    public Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public abstract void work();
}
public abstract class Developer extends Employee{
}
public class JavaEE extends Developer{
    @Override
    public void work() {
        //System.out.println("员工号为:"+getId()+"的"+getName()+"正在开发网站");
        System.out.println("员工号为:"+this.getId()+"的"+this.getName()+"正在开发网站");
    }
}
public class Android extends Developer{
    @Override
    public void work() {
        //System.out.println("员工号为:"+getId()+"的"+getName()+"正在开发app");
        System.out.println("员工号为:"+this.getId()+"的"+this.getName()+"正在开发app");
    }
}
public class Test01 {
    public static void main(String[] args) {
        JavaEE javaEE = new JavaEE();
        javaEE.setId(1);
        javaEE.setName("涛哥");
        javaEE.work();
        System.out.println("===============");
        Android android = new Android();
        android.setId(2);
        android.setName("金莲");
        android.work();
    }
}

方式2:利用构造赋值

public abstract class Employee {
    private int id;
    private String name;

    public Employee() {
    }

    public Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public abstract void work();
}
public abstract class Developer extends Employee{
    public Developer() {
    }

    public Developer(int id, String name) {
        super(id, name);
    }
}
public class JavaEE extends Developer{
    public JavaEE() {
    }

    public JavaEE(int id, String name) {
        super(id, name);
    }

    @Override
    public void work() {
        //System.out.println("员工号为:"+getId()+"的"+getName()+"正在开发网站");
        System.out.println("员工号为:"+this.getId()+"的"+this.getName()+"正在开发网站");
    }
}
public class Android extends Developer{

    public Android() {
    }

    public Android(int id, String name) {
        super(id, name);
    }

    @Override
    public void work() {
        //System.out.println("员工号为:"+getId()+"的"+getName()+"正在开发app");
        System.out.println("员工号为:"+this.getId()+"的"+this.getName()+"正在开发app");
    }
}

public class Test02 {
    public static void main(String[] args) {
        JavaEE javaEE = new JavaEE(1, "涛哥");
        javaEE.work();
        System.out.println("===============");
        Android android = new Android(2, "金莲");
        android.work();
    }
}

  • 18
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值