Java基础的学习、知识点总结

文章目录

Java基础的学习

成长的第二阶段
这是自己的第二阶段的学习,从2019-9-03开始学习,历经一个多月的时间,把 Java基础课程学习完毕,基本了解了 Java的面对对象编程的思想精髓,了解了Java中的类、接口的用法,这是一个漫长的过程,也是一个煎熬的过程,以后的学习任务也是任重而道远!

笔记太长,分了两次上传。

1、

位(bit):一个数字0或者一个数字1,代表一位。

字节(Byte):每逢8位是一个字节,这是数据存储的最小单位。

1 Byte = 8 bit

1 KB = 1024 Byte

1 MB = 1024 KB

1 GB = 1024 MB

1 TB = 1024 GB

1 PB = 1024 TB

1 EB = 1024 PB

1 ZB = 1024 EB

2、MS-DOS(Microsoft Disk Operating System)

命令提示符(cmd)

启动: Win+R,输出cmd回车

切换盘符 盘符名称:

进入文件夹 cd 文件夹名称

进入多级文件夹 cd 文件夹1\文件夹2\文件夹3

返回上一级 cd…

直接回根路径 cd \

查看当前内容 dir

清屏 cls

退出 exit

3、JRE和DJK

  • JRE(Java Runtime Environment): 是Java程序的运行时环境,包含JVM和运行时所需的核心类库。
  • JDK(Java Development Kit): 是Java程序开发工具包,包含JRE和开发人员使用的工具。

我们想要运行一个已有的Java程序,那么只需要安装JRE即可

我们想要开发一个全新的Java程序,那么必须安装JDK

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ohnBFLAe-1573821332897)(C:\Users\Think-Pad\Desktop\java\jdk安装步骤.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L1lTWyWO-1573821333000)(C:\Users\Think-Pad\Desktop\java\jdk安装步骤02.jpg)]

4、环境变量的配置

我的电脑右键打开属性 选择高级系统设置 环境变量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GLKDBZPl-1573821333001)(C:\Users\Think-Pad\Desktop\java\jdk安装步骤03.jpg)]

5、Java程序开发三步骤:编写、编译、运行[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QemFOnc4-1573821333002)(C:\Users\Think-Pad\Desktop\java\Java程序开发的三步骤.jpg)]

  • 编写源代码

  • 编译:cmd中

    javac 类名称.java 回车

    运行:java 类名称 回车

    先编译成class文件,再运行java,运行的是class文件

6、程序的注释

​ 单行注释://这是一行注释信息

​ 多行注释:/*

​ 这是多行注释

​ 这是多行注释 */

​ 也可以用来区块注释

public class HelloWorld{

​ public static void main(String[] args){

​ System.out.println(“Hello,World!”);

}

}

注意:* 源代码第一行的第三个单词必须和所有的文件名称完全一样,大小写也要一样

​ public class 后面代表定义一个类的名称,类是java当中所有源代码的基本组成单位

​ * 第二行的内容是万年不变的固定写法,代表main方法

​ 这一行代表程序执行的起点(从main开始)

​ * 第三行代表打印输出语句(其实就是屏幕显示)

​ 希望显示什么东西,就在小括号中填写什么东西

7、关键字的概念与特征

​ 关键字的特点:

  1. 完全小写字母
  2. 在增强版的记事本当中有特殊颜色

8、标识符(驼峰规则)

标识符是用来给变量、类、包以及方法来命名的。

​ ** 命名规则:

  • 标识符可以包含 英文字母26个(区分大小写)、0-9数字、$(美元符号)和下划线
  • 标识符不能以数字开头
  • 标识符不能是关键字

​ ** 命名规范:

  • 类名规范:首字母大写,后面每个单词首字母大写(大驼峰式)HelloWorld
  • 变量名规范:首字母小写,后面每个单词首字母大写(小驼峰式)helloWorld
  • 方法名规范:同变量名

9、常量的概念与分类

​ 常量:在程序运行期间,固定不变的量

​ 常量的分类:

​ 1.字符串常量:凡是用双引号引起来的部分,叫做字符串常量。例如:“abc”、“Hello”、“1213”

​ 2.整数常量:直接写上的数字,没有小数点。例如:100、200、0、-250

​ 3.浮点型常量:直接写上的数字,有小数点。例如:2.5、-3.14、0.0

​ 4.字符型常量:凡是用单引号引起来的单个字符,就叫做字符常量。例如:‘A’、‘b’、’中‘

​ 5.布尔常量:只有量中取值 true、false

​ 6.空常量:null 代表没有任何数据。

10、常量的打印输出

  • 字符串两个引号之间可以为空
  • 字符型常量中两个引号中间必须有且仅有一个字符,没有不行,有两个也不行
  • 空常量不能直接用来打印输出

11、基本数据类型(八种)

第一类(字符型):char

第二类(布尔型):boolean

第三类(数值类型):

​ 整数型:byte short int long

​ 浮点型:float double

引用数据类型:

​ 字符型、数组、类、接口、Lambda

注意事项:

  1. 字符串不是基本类型,而是引用类型。

  2. 浮点型可能只是一个近似值,并非精确的值

  3. 数据范围与字节数不一定相关,例如float数据范围比long更广泛,但是float是4字节,long是8字节

  4. 浮点数当中默认类型是double,如果一定要使用float类型,需要加上一个后缀F

    如果是整数,默认为int类型,如果一定要使用long类型,需要加上一个后缀L

    推荐使用大写字母后缀

12、变量的概念与定义格式

​ 变量:程序运行期间,内容可以发生改变的量

​ 创建一个变量并使用的格式: 数据类型 变量名称

​ 赋值: 变量名称 = 数据值

​ 一步到位的格式: 数据类型 变量名称 = 数据值

13、变量的注意事项

使用变量的时候,有一些注意事项:

  1. 如果创建多个变量,那么变量之间的名称就不可能重复
  2. 对于float和long类型来说,字母后缀F和L不要丢掉
  3. 如果使用byte或者short类型来说,那么右侧的数据不能超过左侧类型的范围
  4. 没有进行赋值的变量,不能直接使用;一定要赋值后才能使用
  5. 变量使用不能超过作用域的范围 【作用域】:从定义变量的一行开始,一直到直接所属的大括号结束为止
  6. 可以通过一个语句来创建多个变量,但是一般情况下不推荐这么写

14、数据类型转换

​ 当数据类型不一样时,将会发生数据类型转换

自动类型转换(隐式)
 		1. 特点:代码不需要进行特殊处理,自动完成
      2. 规则:数据范围从小到大
强制类型转换(显式)
  1. 特点:代码需要进行特殊转换的格式,不能自动完成

  2. 格式:范围小的类型 范围小的变量名 = (范围小的类型) 原本范围大的数据

    注意事项:
    1. 强制类型转换不推荐使用,因为有可能发生精度损失、数据溢出
    2. byte/short/char这三种类型都可以发生数字运算,例如加法“+”
    3. char类型参与运算时按照ASCII码进行运算 48-‘0’ 65-‘A’ 97-'a’
    4. boolean类型不能发生数据转换(也不能按照0和1)

15、算数运算符-四则运算与取模运算

​ 运算符:进行特定操作的符号,例如:+

​ 表达式:用运算符连起来的式子叫做表达式。例如:20 + 5 a + b

​ 四则运算:

​ 加:+

​ 减:-

​ 乘:*

​ 除:/

​ 取模(取余数):%

​ 首先计算得到表达式的结果,然后再打印输出这个结果

​ 被除数 / 除数 = 商 … 余数

​ 对于一个整数的表达式来说,除法用的是整除,整数除以整数,结果仍然是整数,只看商,不看余数

​ 只有对于整数的除法来说,取模运算符才有余数的意义

注意事项:

​ 1. 一旦运算符当中有不同类型的数据,那么结果将会是数据类型范围大的那种

16、算数运算符

加号的多种用法:

​ 四则运算当中的加号“+”有常见的三种用法:

​ 1.对于数值来说,那就是加法

​ 2.对于字符char类型来说,在计算之前,char会被提升成为int,然后再计算

​ char类型字符和int类型字符之间的对照关系表:ASCII、Unicode

​ 3.对于字符串String(首字母大写,并不是关键字)来说,加号代表字符串连接操作

​ 任何数据类型和字符串进行连接的时候,结果都会变成字符串

自增自减运算符:

​ 自增运算符:++

​ 自减运算符:–

​ 基本含义:让一个变量涨一个数字1,或者让一个变量降一个数字1

​ 使用格式:写在变量名称之前,或者写在变量名称之后。例如:++num,也可以num++

使用方式:

  1. 单独使用:不和其他任何操作混合,自己独立成为一个步骤。

  2. 混合使用:和其他操作混合,例如与赋值混合,或者与打印操作混合,等。

    使用区别:

    1. 在单独使用的时候,前++和后++没有任何区别,也就是:++num;和num++;完全一样的。

    2. 在混合的时候,有【重大区别】

      ​ A. 如果是【前++】,那么变量【立刻马上+1】,然后拿着结果进行使用。 【先加后减】

      ​ B. 如果是【后++】,那么首先使用变量本来的数值,【然后再让变量+1】。 【先用后加】

    注意事项:

    只有变量才能使用自增、自减运算符。常量不可能发生改变,所以不能用。

17、赋值运算符

​ 赋值运算符分别为:

​ 基本赋值运算符:就是一个等号“=”,代表将右侧的数据交给左侧的变量。

​ int a = 30;

​ 复合赋值运算符:

​ += a += 3 相当于 a = a + 3

​ -= b -= 4 相当于 b = b - 4

​ *= c *= 5 相当于 c = c * 5

​ /= d /= 6 相当于 d = d / 6

​ %= e %= 7 相当于 e = e % 7

注意事项:

  1. 只有变量才能使用赋值运算符,常量不能进行赋值。
  2. 复合赋值运算符其中隐含了一个强制类型转换。

18、比较运算符

​ 比较运算符:

​ 大于: >

​ 小于: <

​ 大于等于: >=

​ 小于等于: <=

​ 相等: == 【两个等号连写才相等,一个等号代表的是赋值】

​ 不相等: !=

注意事项:

  1. 比较运算符的结果一定是一个boolean值,成立就是true,不成立就是false

  2. 如果进行多次判断,不能连着写

    数学当中的写法,例如:1 < x < 3

    程序当中**【不允许】**这种写法

19、逻辑运算符

​ 与(并且) && 全部是true,才是true;否则就是false

​ 或(或者) || 至少有一个是true,就是true;全部是false,才是false

​ 非(取反) ! 本来是true,变成false;本来是false,变成true

​ 与“&&”,或“||”,具有短路效果:如果根据左边已经可以判断得到最终结果,那么右边的代码将不再执行,从而节省一定的性能

注意事项:

  1. 逻辑运算符只能用于boolean值

  2. 与、或需要左右各自有一个boolean值,但是取反只要有唯一的一个boolean值即可

  3. 与、或两种运算符,如果有多个条件,可以连续写

    两个条件:条件A && 条件B

    多个条件:条件A && 条件B && 条件C

TIPS:

​ 对于 1 < x < 3的情况,应该拆成两个部分,然后使用与运算符连接起来:

​ int x = 2;

​ 1 < x && x<3

20、三元运算符

​ 一元运算符:只需要一个数据就可以进行操作的运算符。例如:取反!、自增++、自减–

​ 二元运算符:需要两个数据才可以进行操作的运算符。例如:加法+ 、赋值 =

​ 三元运算符:需要三个数据才可以进行操作的运算符。

**格式:**数据类型 变量名称 = 条件判断 ? 表达式A : 表达式B;

流程:

​ 首先判断条件是否成立:

​ 如果成立为true,那么将表达式A的值赋值给左侧的变量;

​ 如果不成立为false,那么将表达式B的值给做左侧的变量;

​ 二者选择其一。

注意事项:

  1. 必须同时保证表达式A和表达式B都符合左侧数据类型的要求
  2. 三元运算符的结果必须被使用

21、方法入门——方法的调用

​ 定义一个方法的格式:

​ public static viod 方法名称(){

​ 方法体;

}

方法名称的命名规则和变量一样,使用小驼峰。

方法体:也就是大括号当中可以包含任意条语句。

注意事项:

  1. 方法定义的先后顺序无所谓。

  2. 方法的定义不能产生嵌套包含关系。

  3. 方法定义好了之后,不会执行的。如果要想执行,一定要进行方法的【调用】。

    如何调用方法,格式:

    ​ 方法名称();

22、编译器的两点优化

​ 对于byte/short/char三种类型来说,如果右侧赋值的数值没有超过范围,那么javac编译器将会自动隐含地为我们补上一个(byte)(short)(cahr)。

​ 1.如果没有超过左侧的范围,编译器补上强转。

  1. 如果右侧超过了左侧范围,那么直接编译器报错。


    在给变量进行赋值的时候,如果右侧的表达式当中全部是常量,没有任何变量,那么编译器javac将会直接将若干个常量表达式计算得到结果。

    short result = 13;

    右侧的常量结果取值,没有超过左侧的范围,所以正确。

​ 这称为“编译器的常量优化”。

​ 但是注意: 一旦表达式当中有变量参与,那么就不能进行这种优化了。

第一章 流程控制

1.1 根据编写顺序,从上往下执行,按顺序执行
1.2 顺序结构

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qP8Mg74r-1573821333004)(C:\Users\Think-Pad\Desktop\java\顺序结构.jpg)]

第二章 判断语句

2.1 判断语句1—— if语句

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oLC01oso-1573821333005)(C:\Users\Think-Pad\Desktop\java\if语句.jpg)]

2.2 判断语句2—— if…else语句

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mVRK0ZuT-1573821333006)(C:\Users\Think-Pad\Desktop\java\if-else语句.jpg)]

2.3 判断语句3—— if…else if…else

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KwDWrKCt-1573821333053)(C:\Users\Think-Pad\Desktop\java\if…else if…else语句.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1zo0sIqp-1573821333055)(C:\Users\Think-Pad\Desktop\java\if…else if…else语句 .jpg)]

第三章 选择语句

3.1 选择语句—— switch语句

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4ZGphu8A-1573821333056)(C:\Users\Think-Pad\Desktop\java\switch语句.jpg)]

最后一个break可以省略,但是强烈不建议省略!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-elD38L8W-1573821333057)(C:\Users\Think-Pad\Desktop\java\switch语句 .jpg)]

3.2 case的穿透性

switch语句使用的注意事项:

  1. 多个case后面的数值不可以重复。

  2. switch后面小括号当中只能是下列数据类型:

    基本数据类型:byte/short/cahr/int

    引用数据类型:String字符串、enum枚举

    1. switch语句格式可以很灵活:前后顺序可以颠倒,而且break语句还可以省略。

    “匹配哪一个case就从哪一个位置向下执行,直到遇到了break或者整体结束为止。”

第四章 循环语句

4.1 循环概念

循环结构的基本组成部分,一般可以分成四部分:

  1. 初始化语句:在循环开始最初执行,而且只做唯一 一次。
  2. 条件判断:如果成立,则循环继续,如果不成立,则循环退出。
  3. 循环体:重复要做的事情内容,若干行语句。
  4. 步进语句:每次循环之后都要执行的扫尾工作,每次循环之后都要执行一次。
4.2 循环语句1—— for循环

​ for(初始化表达式;布尔表达式;步进表达式){

​ 循环体;

}

4.3 循环语句2—— while

​ while循环有一个标准格式,还有一个扩展模式。

​ 标准格式:

​ while(条件判断){

​ 循环体

}

​ 扩展格式:

​ 初始化语句;

​ while(条件判断){

​ 循环体;

​ 步进语句;

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rVb9uHDx-1573821333058)(C:\Users\Think-Pad\Desktop\java\循环结构.jpg)]

4.4 循环语句3—— do…while

​ do-while循环的标准格式:

​ do{

​ 循环体

}while(条件判断);

​ 初始化语句:

​ do{

​ 循环体

​ 步进语句

}while(条件判断);

4.5 循环语句的区别

​ 三种循环的区别:

  1. 如果条件从来没有满足过,那么for循环和while循环将会执行0次,但是do-while循环会执行至少一次。
  2. for循环的变量在小括号当中定义,只有循环内部能用。while循环和do-while循环初始化语句本来就在外面,所以出来循环之后还可以继续使用。
4.6 跳出语句 break continue

break关键字的用法有常见的两种:

  1. 可以用在switch语句当中,一旦执行,整个switch语句立刻结束。

  2. 还可以用在循环语句中,一旦执行,整个循环语句立刻结束。打断循环。

    关于循环的选择,有一个小建议:

    凡是次数确定的场景多用for循环,否则多用while循环。

    continue关键字:

    另一种循环控制语句是continue关键字。

    一旦执行,立刻跳过当前次数循环剩余内容,马上开始下一次循环。

    死循环:

    永远停不下来的循环,叫做死循环。

    死循环的标准格式:

    while(ture){

    ​ 循环体

    }

第五章 IDEA的使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uka9Fym3-1573821333059)(C:\Users\Think-Pad\Desktop\java\IDEA常用的快捷键.jpg)]

第六章 方法

6.1 方法的定义格式

​ 方法其实就是若干语句的功能集合。

​ 方法好比是一个工厂。

​ 参数(原料):就是进入方法的数据。

​ 返回值(产出物):就是从方法中出来的数据。

定义方法的完整格式:

​ 修饰符 返回类型值 方法名称(参数类型 参数名称,…){

​ 方法体

​ return 返回值;

}

​ 修饰符:现阶段的固定写法,public static

​ 返回值类型:也就是方法最终产生的数据结果是什么类型

​ 方法名称:方法的名字,规则和变量一样,小驼峰

​ 参数类型:进入方法的数据是什么类型

​ 参数名称:进入方法的数据对应的变量名称

ps:参数如果有多个,使用逗号分离

​ 方法体:方法需要做的事,若干行代码

​ return:两个作用,第一停止当前方法,第二将后面的返回值还给调用处

​ 返回值:也就是方法执行后最终产生的数据结果

注意:return后面的“返回值”,必须和方法名称前面的“返回值类型”,保持对应

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-McAnLrM5-1573821333061)(C:\Users\Think-Pad\Desktop\java\实例.jpg)]

6.2 方法的三种调用格式

​ 方法的三种调用格式:

  1. 单独调用:方法名称(参数);
  2. 打印调用:System.out.println(方法名称(参数));
  3. 赋值调用:数据类型 变量名称 = 方法名称(参数);

注意:此前学习的方法,返回值类型固定写为void,这种写法只能够单独使用,不能进行打印调用或者赋值调用。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j05dD9vb-1573821333062)(C:\Users\Think-Pad\Desktop\java\实例.jpg)]

6.3 对比有参数和无参数

​ 有参数:小括号当中有内容,当一个方法需要一些数据条件,才能完成任务时,就是有参数。

​ 例如有两个数字相加,必须知道两个数字各自是多少,才能相加。

​ 无参数:小括号当中留空,一个方法不需要任何数据条件,自己就能独立完成任务,就是无参数。

​ 例如定义一个方法,打印固定10次HelloWorld。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eipd4K6O-1573821333078)(C:\Users\Think-Pad\Desktop\java\对比有无参数.jpg)]

6.4 对比有返回值和无返回值

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zCu530pX-1573821333079)(C:\Users\Think-Pad\Desktop\java\对比有无返回值.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LKgeIrT7-1573821333080)(C:\Users\Think-Pad\Desktop\java\实例01.jpg)]

错误写法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WpvVNyXA-1573821333081)(C:\Users\Think-Pad\Desktop\java\错误写法.jpg)]

6.5 练习题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NvQpDNuD-1573821333082)(C:\Users\Think-Pad\Desktop\java\1到100累加.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8uWZ5YeJ-1573821333083)(C:\Users\Think-Pad\Desktop\java\打印指定次数的HelloWorld.jpg)]

方法的注意事项:

使用方法的时候,注意事项:

  1. 方法应该定义在类当中,但是不能在方法当中再定义方法,不能嵌套。
  2. 方法定义的前后顺序无所谓。
  3. 方法定义之后不会执行,如果希望执行,一定要调用:单独调用、打印调用、赋值调用。
  4. 如果方法有返回值,那么必须写上“return 返回值”,不能没有。
  5. return后面的返回值数据,必须和方法的返回值类型对应起来。
  6. 对于一个void没有返回值的方法,不能写return后面的返回值,只能写return自己。
  7. 对于void方法当中最后一行的return可以省略不写。
  8. 一个方法当中可以有多个return语句,但是必须保证同时只有一个被执行到 ,两个return不能连写。
方法重载的基本使用:

​ 对于功能类似的方法来说,因为参数列表不一样,却需要记住那么多不同的方法名称,太麻烦。

​ 方法的重载(Overload):多个方法的名称一样,但是参数列表不一样。

​ 好处:只需要记住唯一一个方法名称,就可以实现类似的多个功能。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZCJ6oOXE-1573821333085)(C:\Users\Think-Pad\Desktop\java\方法的重载.jpg)]

方法的重载与下列因素相关:

  1. 参数个数不同
  2. 参数类型不同
  3. 参数的多类型顺序不同

方法重载与下列因素无关:

  1. 与参数的名称无关
  2. 与方法的返回值类型无关

println就是一个重载

第七章 数组

7.1 数组的概念

​ 数组的概念:是一种容器,可以同时存放多个数据值。

数组的特点:

  1. 数组是一种引用数据的类型
  2. 数组当中的多个数据类型必须统一
  3. 数组的长度在程序运行期间不可改变
7.2 数组的定义格式

​ 数组的初始化:在内存中建立一个数组,并且向其中赋予一些默认值。

​ 两种常见的初始化方式:

  1. 动态初始化(指定长度):在创建数组的时候,直接指定数组当中的数据元素的个数。
  2. 静态初始化(指定内容):在创建数组的时候,不直接指定数据个数多少,而是直接将具体的数据内容进行指定。

动态初始化数组的格式:

数据类型[ ] 数组名称 = new 数据类型[数组长度];

解析含义:

左侧数据类型:也就是数组当中保存的数据,全部是统一的什么类型

左侧的中括号:代表我是一个数组

左侧的数组名称:给数组取一个名字

右侧的new:代表创建数组的动作

右侧数据类型:必须和左边的数据类型保持一致

右侧中括号的长度:也就是数组当中,到底可以保存多少个数据,是一个int数字

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1w70zd1v-1573821333086)(C:\Users\Think-Pad\Desktop\java\数组的定义.jpg)]

静态初始化基本格式:

数据类型[ ] 数组名称 = new 数据类型[ ]{ 元素1,元素2,…};

注意事项:

虽然静态初始化没有直接告诉长度,但是根据大括号里面元素的具体内容,也可以自动推算出来长度。

静态初始化省略格式:

数据类型[ ] 数组名称 = { 元素1,元素2,…};

注意事项:

  1. 静态初始化没有直接指定长度,但是仍然会自动推算得到长度。
  2. 静态初始化标准格式可以拆分成为两个步骤。
  3. 动态初始化也可以拆分成两个步骤。
  4. 静态初始化一旦使用省略格式,就不能拆分成两个步骤了。

使用建议:

​ 如果不确定数组当中的具体内容,用动态初始化;否则,已经确定了具体的内容,用静态初始化。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NrwHe0xV-1573821333087)(C:\Users\Think-Pad\Desktop\java\数组初始化.jpg)]

7.3 访问数组元素进行获取

​ 直接打印数组名称,得到的是数组对应的:内存地址哈希值。

​ 二进制:01

​ 十进制:0123456789

​ 16进制:0123456789adcdef

​ 访问数组元素的格式:数组名称【索引值】

​ 索引值:就是一个int数字,代表数组当中的编号 。

注意:索引值从0开始,一直到“数组的长度-1”为止。

7.4 访问数组元素进行赋值

​ 使用动态初始化数组时候,其中的元素将会自动拥有一个默认值。规则如下:

​ 如果是整数类型,那么默认值为0

​ 如果是浮点类型,那么默认值为0.0

​ 如果是字符类型,那么默认值为’\u0000’

​ 如果是布尔类型,那么默认值为false

​ 如果是引用类型,那么默认值为null

注意事项:

​ 静态初始化其实也有默认值的过程,只不过系统自动马上将默认值替换成为了大括号当中的具体数值。

第八章 Java中的内存划分

8.1 Java的内存需要划分成为5个部分
  1. 栈(Stack):存放的都是方法中的局部变量。方法的运行一定要在栈当中运行。

    ​ 局部变量:方法的参数,或者是方法{}内部的变量

    ​ 作用域:一旦超出作用域,立刻从栈内存当中消失

    1. 堆(Heap):凡是new出来的东西,都在堆当中。

    ​ 堆里面的东西都有一个地址值:16进制

    ​ 堆内存里面的数据,都有默认值。规则:

    ​ 如果是整数类型,那么默认值为0

    ​ 如果是浮点类型,那么默认值为0.0

    ​ 如果是字符类型,那么默认值为’\u0000’

    ​ 如果是布尔类型,那么默认值为false

    ​ 如果是引用类型,那么默认值为null

    1. 方法区(Method Area):存储.class相关信息,包含方法的信息。
    2. 本地方法栈(Nation Method Stack):与操作系统相关。
    3. 寄存器(pc Register):与cpu相关 。
8.2 一个数组的内存图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AWEs2AuS-1573821333088)(C:\Users\Think-Pad\Desktop\java\一个数组的内存图.jpg)]

8.3 两个引用指向同一个数组的内存

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kKoxNZvA-1573821333089)(C:\Users\Think-Pad\Desktop\java\两个引用指向同一个数组的内存.jpg)]

8.4 数组索引越界异常

​ 数组的索引编号从0开始,一直到“数组的长度-1”为止。

​ 如果访问数组元素的时候,索引编号并不存在,那么将会发生数组索引越界异常

8.5 空指针异常

​ 所有的引用类型变量,都可以赋值为一个null值,但是代表其中什么都没有。

​ 数组必须进行new初始化才能使用其中的元素。

​ 如果只是赋值了一个null,没有进行new创建,那么将会发生空指针异常。

8.6 获取数组的长度

​ 获取数组的长度,格式:

​ 数组名称.length

​ 这将会得到一个int数字,代表数组的长度。

​ 数组一旦创建,程序运行期间,长度不可变。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5Q8wx2GQ-1573821333270)(C:\Users\Think-Pad\Desktop\java\获取数组的长度.jpg)]

8.7 数组的遍历输出

​ 遍历数组,就是说对数组当中每一个元素进行逐一、挨个儿处理。默认的处理方式就是打印输出。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bDpZszHX-1573821333279)(C:\Users\Think-Pad\Desktop\java\求出数组中的最值.jpg)]

8.8 数组元素反转

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ukIJyBAZ-1573821333321)(C:\Users\Think-Pad\Desktop\java\数组元素反转.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vaHbaQjp-1573821333323)(C:\Users\Think-Pad\Desktop\java\数组元素反转 .jpg)]

8.9 数组作为方法参数

​ 数组可以作为方法参数。

​ 当调用方法的时候,向方法的小括号进行传参,传递进去的其实是数组的地址值。

8.10 数组作为方法返回值

​ 一个方法可以有0、1、多个参数,但是只能有0或者1个返回值,不能有多个返回值。

​ 如果希望一个方法当中产生了多个结果数据进行返回,怎么办?

​ 解决方案:使用一个数组作为返回值类型即可。

​ 任何数据类型都能作为方法的参数类型,或者返回值类型。

​ 数组作为方法的参数,传递进去的其实是数组的地址值。

​ 数组作为方法的返回值,返回的其实也是数组的地址值。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nZZCb8ja-1573821333333)(C:\Users\Think-Pad\Desktop\java\数组作为返回值.jpg)]

第九章 面向对象思想

9.1 面向对象思想的概念

​ 面向过程:当需要实现一个功能的时候,每一个具体的步骤都要亲力亲为,详细处理每一个细节。

​ 面向对象:当需要实现一个功能的时候,不关心具体的步骤,而是找一个已经具有该功能的人,来帮我做事儿。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hUbNu56c-1573821333335)(C:\Users\Think-Pad\Desktop\java\面向对象.jpg)]

9.2 类和对象
  • 类: 是一组相关属性行为的集合。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该类事物。

  • **属性:**就是该事物的状态信息。

  • **行为:**就是该事物能够做什么。

  • **对象:**是一类事物的具体体现。对象是类的一个实例,必然具备该类事物的属性和行为。

类与对象的关系:

  • 类是对一类事物的描述,是抽象的
  • 对象是一类事物的实例,是具体的
  • 类是对象的模板,对象是类的实体
9.3 类的定义

​ 成员变量(属性):

​ String name;// 姓名

​ int age; // 年龄

​ 成员方法(行为);

​ public void eat(){} // 吃饭

​ public void sleep(){} // 睡觉

​ public void study(){} // 学习

注意事项:

  1. 成员变量是直接定义在类当中的,在方法外边。
  2. 成员方法不要写static关键字。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QzNNrGs8-1573821333336)(C:\Users\Think-Pad\Desktop\java\类的定义.jpg)]

9.4 对象的创建及其使用

​ 通常情况下,一个类并不能直接使用 ,需要根据类创建一个对象,才能使用。

  1. **导包:**也就是指出需要使用的类在什么位置。

    import 包名称.类名称;

    import cn.Demo;

    对于和当前类属于同一个包的情况,可以省略导包语句不写。

    1. **创建,**格式:

    类名称 对象名 = new 类名称();

    Student stu = new Student();

    1. **使用,**分为两种情况:

    使用成员变量:对象名.成员变量名

    使用成员方法:对象名.成员方法名(参数)

    (也就是,想用谁,就用对象名点儿谁。)

注意事项:

如果成员变量没有进行赋值,那么将会有一个默认值,规则和数组一样。

9.5 一个对象的内存图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oW3PMHv8-1573821333337)(C:\Users\Think-Pad\Desktop\java\一个对象的内存图.jpg)]

9.6 两个对象使用同一个方法的内存图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wwbhK9Sg-1573821333339)(C:\Users\Think-Pad\Desktop\java\两个对象使用同一个方法的内存图.jpg)]

9.7 两个引用指向同一个对象的内存图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jj5d6GWk-1573821333340)(C:\Users\Think-Pad\Desktop\java\两个引用指向同一个对象的内存图.jpg)]

9.8 使用对象类型作为方法的参数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LfgWVYKU-1573821333342)(C:\Users\Think-Pad\Desktop\java\使用对象类型作为方法的参数.jpg)]

9.9 使用对象类型作为方法的返回值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9rtsWsez-1573821333343)(C:\Users\Think-Pad\Desktop\java\使用对象类型作为方法的返回值.jpg)]

9.10 局部变量和成员变量的区别
  1. 定义的位置不一样【重点】

    局部变量:在方法的内部

    成员变量:在方法的外部,直接写在类当中

    1. 作用范围不一样【重点】

    局部变量:只有方法当中才能使用,出了方法就不能用

    成员变量:整个类都可以通用

    1. 默认值不一样【重点】

    局部变量:没有默认值,如果要想使用,必须手动进行赋值

    成员变量:如果没有赋值,会有默认值,规则和数组一样

    1. 内存的位置不一样(了解)

    局部变量:位于栈内存

    成员变量:位于堆内存

    1. 生命周期不一样(了解)

    局部变量:随着方法进栈而诞生,随着方法出栈而消失

    成员变量:随着对象创建而诞生,随着对象被垃圾回收而消失

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UMTST6jl-1573821333344)(C:\Users\Think-Pad\Desktop\java\成员变量和局部变量的区别.jpg)]

9.11 面向对象三大特征之封装

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

​ 封装性在Java当中的体现:

  1. 方法就是一种封装
  2. 关键字private也是一种封装

​ 封装就是将一些细节信息隐藏起来 ,对于外界不可见

9.12 private关键字的作用

​ 问题描述:定义person的年龄时,无法阻止不合理的数值被设置进来。

​ 解决方案:用private关键字将需要保护的成员进行修饰。

​ 一旦使用了private进行修饰,那么本类当中仍然可以随意访问。

​ 但是!超出了本类范围之外就不能再直接访问了。

​ 间接访问private成员变量,就是定义一对儿getter/setter方法

​ 必须叫setXxx或者是getXxx命名规则。

对于getter来说,不能有参数,返回值类型和成员变量对应;

对于setter来说,不能有返回值,参数类型和成员变量对应 。

对于基本类型当中的Boolean值,getter方法一定要写成isXxx的形式,而setXxx规则不变。

9.13 this关键字的作用

​ 当方法的局部变量和类的成员变量重名的时候,根据**“就近原则”**,优先使用局部变量。

​ 如果需要访问本类当中的成员变量,需要使用格式:

​ this.成员变量名

​ “通过谁调用的方法,谁就是this”

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PbQFOytV-1573821333345)(C:\Users\Think-Pad\Desktop\java\this关键字02.jpg)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GsmoBAOC-1573821333410)(C:\Users\Think-Pad\Desktop\java\this关键字01.jpg)]

9.14 构造方法

​ 构造方法是专门用来创建对象的方法,当我们通过关键字new来创建对象时,其实就是在调用构造方法。

​ 格式:

​ public 类名称(参数类型 参数名称){

​ 方法体;

​ }

注意事项:

  1. 构造方法的名称必须和所在的类名称完全一样,就连大小写也要一样。

  2. 构造方法不要写返回值类型,连void都不写。

  3. 构造方法不能return一个具体的返回值。

  4. 如果没有编写任何构造方法,那么编译器将会默认赠送一个构造方法,没有参数、方法体什么事儿都不做。

    public Student(){}

    1. 一旦编写了至少一个构造方法,那么编译器将不再赠送。
    2. 构造方法也是可以进行重载的。

    重载:方法名称相同,参数列表不同。

9.15 定义一个标准的类

​ 一个标准的类通常要拥有下面四个组成部分:

  1. 所有的成员变量都要使用private关键字修饰

  2. 为每一个成员变量编写一对儿getter/setter方法

  3. 编写一个无参数的构造方法

  4. 编写一个全参数的构造方法

    这样标准的类也叫做Java Bean

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1FJAvtle-1573821333412)(C:\Users\Think-Pad\Desktop\java\一个标准的类.jpg)]

第十章 API文档的使用

10.1 Scanner的使用步骤

​ Scanner类的功能:可以实现键盘输入数据到程序中。

引用类型的一般使用步骤:

  1. 导包

    import 包路径.类名称;

    import java.util.Scanner;

    如果需要使用的目标类和当前类位于同一个包下,则可以省略导包语句不写。

    只有Java.lang包下的内容不需要导包,其他的包都需要import语句。

    1. 创建

    类名称 对象名 = new 类名称();

    1. 使用

    对象名.成员方法名()

获取键盘输入的一个int数字;int num = sc.nextInt();

获取键盘输入的一个字符串:String str = sc.next();

10.2 匿名对象

​ 匿名对象就是只有右边的对象,没有左边的名字和赋值运算符。

​ new 类名称();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wSlUxXAV-1573821333413)(C:\Users\Think-Pad\Desktop\java\使用匿名对象.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-giyEek46-1573821333414)(C:\Users\Think-Pad\Desktop\java\使用匿名对象 .jpg)]

10.3 Random概念和基本使用

​ Random类用来生成随机数字。使用起来也是三个步骤:

  1. 导包

    import java.util.Random;

    1. 创建

    Random r = new Random(); // 小括号当中留空即可

    1. 使用

    获取一个随机的int数字(范围是int所有范围,有正负两种);int num = r.nextInt();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QVIFcey7-1573821333415)(C:\Users\Think-Pad\Desktop\java\生成Random随机数.jpg)]

生成指定范围的随机数 :

获取一个随机的int数字(参数代表了范围,左闭右开区间):int num = r.nextInt(3);

实际上代表的含义是:[0,3),也就是0~2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pk018w6n-1573821333419)(C:\Users\Think-Pad\Desktop\java\Random生成指定范围随机数.jpg)]

生成1~n 之间是随机数:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VmY39ygW-1573821333421)(C:\Users\Think-Pad\Desktop\java\Random生成随机数 .jpg)]

10.4 猜数字游戏

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YdPezW0P-1573821333423)(C:\Users\Think-Pad\Desktop\java\猜数字游戏01.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ae6ao3d-1573821333424)(C:\Users\Think-Pad\Desktop\java\猜数字游戏02.jpg)]

10.5 对象数组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gnRyFQi2-1573821333426)(C:\Users\Think-Pad\Desktop\java\对象数组.jpg)]

10.6 ArrayList集合概述和基本使用

​ 数组的长度不可以发生改变。

但是ArrayList集合的长度是可以随意变化的。

​ 对于ArrayList来说,有一个尖括号代表泛型。

​ 泛型:也就是装在集合当中的所有元素,全都是统一的什么类型。

注意:泛型只能是引用类型,不能是基本类型。

​ 注意事项:

对于ArrayList集合来说,直接打印得到的不是地址值,而是内容。

​ 如果内容为空,得到的是空的中括号:[ ]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6xbFQDWF-1573821333427)(C:\Users\Think-Pad\Desktop\java\ArrayList的使用.jpg)]

10.7 ArrayList集合的常用方法和遍历

ArrayList当中的常用方法有:

​ **public boolean add( E e)😗*向集合当中添加元素,参数的类型和泛型一致。返回值代表添加是否成功。

​ 备注:对于ArrayList 集合来说,add添加动作一定是成功的,所以返回值可用可不用。

​ 但是对于其它集合(今后学习)来说,add添加动作不一定成功。

​ **public E get (int index)😗*从集合当中获取元素,参数是索引编号,返回值就是对应位置的元素。

public E remove(int index): 从集合当中删除元素,参数是索引值编号,返回值就是被删除掉的元素。

public int size(): 获取集合的尺寸长度,返回值是集合中包含的元素个数。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xsaAOGBY-1573821333429)(C:\Users\Think-Pad\Desktop\java\ArrayList常用方法.jpg)]

ArrayList集合的遍历:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FKERU0Wt-1573821333430)(C:\Users\Think-Pad\Desktop\java\ArrayList集合的遍历.jpg)]

10.8 ArrayList集合存储基本数据类型

​ 如果希望向集合ArrayList当中存储基本数据类型,必须使用基本类型对应的“包装类”。

泛型只能是引用类!

​ 基本类型 包装类(引用类型,包装类都位于java.lang包下)

​ byte Byte

​ short Short

​ int Integer 【特殊】

​ long Long

​ float Float

​ double Double

​ char Character 【特殊】

​ boolean Boolean

从 JDK1.5+ 开始,支持自动装箱、自动拆箱。

自动装箱:基本类型 – > 包装类型

自动拆箱:包装类型 – > 基本类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2wawzNHB-1573821333432)(C:\Users\Think-Pad\Desktop\java\ArrayList储存基本数据类型.jpg)]

10.9 ArrayList练习

1.

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PYq7jkxv-1573821333434)(C:\Users\Think-Pad\Desktop\java\ArrayList练习.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zS7v3Gna-1573821333435)(C:\Users\Think-Pad\Desktop\java\ArrayList练习01.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OZjYaMzk-1573821333437)(C:\Users\Think-Pad\Desktop\java\ArrayList练习01 .jpg)]

第十一章 字符串

11.1 字符串的概念和特点

​ java.lang.String类代表字符串。

​ API当中说:Java程序中的所有字符串字面值(如"abc")都作为此类的实例实现。

​ 其实就是说:程序当中所有的双引号字符串,都是String类对象。(就算是没有new,也照样是。)

字符串的特点:

  1. 字符串的内容永不可变。【重点】
  2. 正是因为字符串不可改变,所以字符串是可以共享使用的。
  3. 字符串效果上相当于是char[ ]字符数组,但是底层原理是byte[ ]字节数组。

​ 创建字符串的常见3+1种方式。

​ 三种构造方法:

​ public String(): 创建一个空白字符串,不含任何内容。

​ public String(char[ ] array): 根据字符数组的内容,来创建对应的字符串。

​ public String(byte[ ] array): 根据字节数组的内容,来创建对应的字符串。

​ 一种直接创建:

​ String str = “Hello”; // 右边直接用双引号

​ 注意:直接写上双引号,就是字符串对象。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YleQ7hnS-1573821333438)(C:\Users\Think-Pad\Desktop\java\字符串.jpg)]

11.2 字符串的常量池

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iEEyWFWq-1573821333440)(C:\Users\Think-Pad\Desktop\java\字符串的常量吃池.jpg)]

11.3 字符串的比较相关方法

​ == 是进行对象的地址值比较,如果确实需要字符串的内容,可以使用两个方法:

public boolean aquals(Object obj): 参数可以是任何对象,只有参数是一个字符串并且内容相同的才会给true;否则返回false。

​ 注意事项:

  1. 任何对象都能用Object进行接收。

  2. equals方法具有对称性,也就是 a.equals(b)和b.equals(a) 效果一样。

  3. 如果比较双方一个常量一个变量,推荐把常量字符串写在前面。

    推荐:“abc”.equals(str) 不推荐:str.equals(“abc”)

public boolean equalsIgnoreCase(String str): 忽略大小写,进行内容比较。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6lfjBqiI-1573821333441)(C:\Users\Think-Pad\Desktop\java\字符串比较.jpg)]

11.4 字符串的获取相关方法

​ String 当中与获取相关的常用方法有:

public int length(): 获取字符串当中含有的字符个数,拿到字符串长度。

public String concat(String str): 将当前字符串和参数字符串拼接成为返回值新的字符串 。

public char charAt(int index): 获取指定索引位置的单个字符。(索引从0开始。)

public int indexof(String str): 查找参数字符串在本字符串当中首次出现的索引位置,如果没有返回 -1 值。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w00jRZUe-1573821333442)(C:\Users\Think-Pad\Desktop\java\字符串 .jpg)]

11.5 字符串的截取方法

public String substring(int index): 截取从参数位置一直到字符串末尾,返回新字符。

public String substring(int begin, int end): 截取从begin开始,一直到end结束,中间的字符串。

备注: [begin,end), 包含左边,不包含右边。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ijscpedn-1573821333444)(C:\Users\Think-Pad\Desktop\java\字符串的截取方法.jpg)]

11.6 字符串的转换相关方法

​ String当中与转换相关的常用方法有:

public char[ ] toCharArray(): 将当前字符串拆分成为字符数组作为返回值。

public byte[ ] getByte(): 获取当前字符串底层的字节数组。

public String replace(CharSequence oldString,CharSequence newString);

​ 将所有出现的老字符串替换成为新的字符串,返回替换之后的结果新字符串。

​ **备注:**CharSequence意思就是说可以接受字符串类型。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lI9knImC-1573821333445)(C:\Users\Think-Pad\Desktop\java\字符串转换.jpg)]

11.7 字符串的分割方法

public String[ ] split(String regex): 按照参数的规则,将字符串切分成为若干部分。

注意事项:

​ split方法的参数其实就是一个“正则表达式”,今后学习。

​ 今天要注意:如果按照英文句点“.”进行切分,必须写“\ \ .”(两个反斜杠)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xsXFoVEY-1573821333446)(C:\Users\Think-Pad\Desktop\java\字符串的分割.jpg)]

11.8 字符串练习

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pMXD4Pt5-1573821333448)(C:\Users\Think-Pad\Desktop\java\字符串方法练习.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kFaJ9yEs-1573821333449)(C:\Users\Think-Pad\Desktop\java\字符串练习01.jpg)]


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9meJFtTF-1573821333450)(C:\Users\Think-Pad\Desktop\java\字符串方法的练习03.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t9o40LEH-1573821333451)(C:\Users\Think-Pad\Desktop\java\字符串方法的练习04.jpg)]

第十二章 静态static关键字

12.1 静态static关键字概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zcVfOCqC-1573821333453)(C:\Users\Think-Pad\Desktop\java\静态static关键字概述.jpg)]

12.2 静态static关键字修饰成员变量

​ 如果一个成员变量使用了static关键字,那么这个变量不再属于对象自己,而是属于所在的类。多个对象共享同一份数据。

12.3 静态static关键字修饰成员方法

​ 一旦使用static修饰成员方法,那么这就成为了静态方法。静态方法不属于对象,而是属于类的。

如果没有static关键字,那么必须首先创建对象,然后通过对象才能使用它。

如果有了static关键字,那么不需要创建对象,直接就能通过类名称进行调用。

​ 无论是成员变量,还是成员方法。如果有了static,都推荐使用类名称进行调用。

​ 静态变量:类名称.静态变量

​ 静态方法:类名称.静态方法() (在同一个类中,可以省略类名称)

​ 注意事项:

  1. 静态不能直接访问非静态。

    原因:因为在内存当中是【先】有的静态内容,【后】有的非静态内容。

    “先人不知道后人,但是后人知道先人”

    1. 静态方法当中不能使用this关键字。

    原因:this代表对象,通过谁调用的方法,谁就是当前对象。

12.4 静态static的内存图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uWU6M314-1573821333454)(C:\Users\Think-Pad\Desktop\java\静态static的内存图 .jpg)]

12.5 静态代码块

​ 静态代码块的格式是:

​ public class 类名称{

​ static{

​ // 静态代码块的内容

​ }

​ }

特点:当第一次用到本类时,静态代码块执行唯一的一次。

静态内容总是优先于非静态,所以静态代码块方法先执行。

静态代码块的经典用途:

用来一次性的对静态成员变量进行赋值。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uzqJWDNw-1573821333456)(C:\Users\Think-Pad\Desktop\java\静态代码块01.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qnZTBNM6-1573821333457)(C:\Users\Think-Pad\Desktop\java\静态代码块02.jpg)]

12.6 数组工具类Arrays

​ java.util.Arrays是一个与数组相关的工具类,里面提供了大量静态方法,用来实现数组常见的操作。

public static String toString(数组): 将参数数组变成字符串(按照默认格式:[元素1,元素2,元素3…])

public static void sort(数组): 按照默认升序(从小到大)对数组的元素进行排序。

备注:

  1. 如果是数值,sort默认按照升序从小到大
  2. 如果是字符,sort默认值按照字母升序
  3. 如果是自定义的类型,那么这个自定义的类需要有Comparable或者Comparator接口的支持。(今后学习)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SvYPp7ZI-1573821333458)(C:\Users\Think-Pad\Desktop\java\数组排列.jpg)]

练习:

package cn.code;

import java.lang.reflect.Array;
import java.util.Arrays;

/*
题目:
请使用Arrays相关的API,将一个随机字符串中的所有字符升序排列,并倒序打印。
 */
public class Demo34 {
    public static void main(String[] args) {
        String str = "rdtyftuyi4865fyugyio";

        // 如何进行升序排列:sort
        // 必须是一个数组才能用Arrays.sort方法
        // String --> 数组,用toCharArray

        char[] chars = str.toCharArray();
        Arrays.sort(chars);  //  升序排列

        for (int i = chars.length - 1; i >= 0; i--) {
            System.out.println(chars[i]);
        }

    }
}
12.7 数学工具类Math
package cn.code;
/*
java.util.math类是数学相关的工具类,里面提供了大量的静态方法,完成与数学运算相关的操作。

public static double abs(double num): 获取绝对值。有多种重载。
public static double ceil(double num):向上取整
public static double floor(double num):向下取整
public static long round(double num): 四舍五入
 */
public class Demo35 {
    public static void main(String[] args) {
        System.out.println(Math.abs(-20.2));  //  20.2
        System.out.println(Math.ceil(20.2));  //  21.0
        System.out.println(Math.floor(20.2));  //  20.0
        System.out.println(Math.round(20.2));  //  20
    }
}

练习:

package cn.code;
/*
题目:
计算在-10.8到5.9之间,绝对值大于6或者小于2.1的整数有多少个?

分析:
1. 既然已经确定了范围,for循环
2. 起点位置-10.8应该转换成为-10,两种方法:
    2.1 可以使用Math.ceil方法向上(向正方向)取整
    2.2 强转成为int,自动舍弃所有小数位
3. 每一个数字都是整数,所以步进表达式应该是num++,这样每次都是+1的
4. 如何拿到绝对值:Math.abs方法
5. 一旦发现了一个数字,需要让计时器++进行统计

备注: 如果使用MAth.ceil方法,-10.8可以变成-10.0,注意double也是可以进行++的。

 */
public class Demo36 {
    public static void main(String[] args) {
        int count = 0;  //  计时器

        double a = -10.8;
        double b = 5.9;
        //  得到a与b之间所有的整数
        for (int i = (int) a; i < b; i++) {
            int abs = Math.abs(i);
            if (abs > 6 || abs < 2.1){
                System.out.println(i);
                count++;
            }
        }
        System.out.println("总共有:" + count);
    }
}

第十三章 继承

13.1 继承的概念

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FOCnTQlR-1573821333460)(C:\Users\Think-Pad\Desktop\java\继承的概念.jpg)]

13.2 继承的格式

main方法:

package cn.code;
/*
在继承的关系中,“子类就是一个父类”。也就是说,子类可以当做父类看待。
例如父类是员工,子类就是讲师,那么“讲师就是一个员工”。关系:is-a

定义父类的格式:(一个普通的类定义)
public class 父类名称{
    //...
}

定义子类的格式:
public class 子类名称 extends 父类名称{
    //...
}

 */
public class Demo37 {
    public static void main(String[] args) {
        Demo3702 dem = new Demo3702();  //  创建子类对象
        dem.method();  //  中秋节快乐!
    }
}

父类方法:

package cn.code;

public class Demo3701 {
    public void method(){
        System.out.println("中秋节快乐!");
    }
}

子类方法:

package cn.code;

import cn.code.Demo.Demo3201;

public class Demo3702  extends Demo3701 {

}
13.3 继承中成员变量的访问特点

main方法:

package cn.code;
/*
在父类的继承关系当中,如果成员变量重名,则创建子类对象时,访问有两种:

直接通过子类对象访问成员变量:
    等号左边是谁,就优先用谁,没有则向上找。
间接通过成员方法访问成员变量:
    该方法属于谁,就优先用谁,没有则向上找。
 */
public class Demo38 {
    public static void main(String[] args) {
        Demo3802 zi = new Demo3802();
        System.out.println(zi.num);  //  865

        zi.methZi();  //  中秋节快乐!
        zi.methodFu();  //  节日快乐!
    }
}

父类方法:

package cn.code;

public class Demo3801 {
        int numFu = 51;
        int num = 85;

        public void methodFu(){
            System.out.println("节日快乐!");
    }
}

子类方法 :

package cn.code;

public class Demo3802 extends Demo3801{

        int numZi = 754;
        int num = 865;

        public void methZi(){
            System.out.println("中秋节快乐!");
        }
}
13.4 区分子类方法中重名的三种变量

main方法:

package cn.code;
/*
局部变量:   直接写成员变量名
本类的成员变量:    this.成员变量名
父类的成员变量名:   super.成员变量名
 */
public class Demo39 {
    public static void main(String[] args) {
        Demo3902 deo = new Demo3902();
        deo.method();  //  65  25  10
    }
}

父类方法:

package cn.code;

public class Demo3901 {
    int num = 10;
}

子类方法:

package cn.code;

public class Demo3902 extends Demo3901{
    int num = 25;
    public void method(){
        int num = 65;
        System.out.println(num);
        System.out.println(this.num);
        System.out.println(super.num);
    }
}
13.5 继承中成员方法的访问特点

main方法:

package cn.code;
/*
在子类的继承关系当中,创建子类对象,访问成员方法的规则:
    创建的对象是谁,就优先用谁,如果没有则向上找。

注意事项:
无论是成员方法还是成员变量,如果没有都是向上找父类,绝对不会向下找子类的。
*/
public class Demo40 {
       public static void main(String[] args) {
        //  创建一个子类的对象
        Demo4002 deo = new Demo4002();
        //  创建的对象是子类的,所以优先使用子类方法
        deo.method();  //  子类重名方法执行啦!
        deo.methodZi();  //  子类方法执行啦!
        deo.methodFu();  //  父类方法执行啦!
    }
}

父类方法:

package cn.code;

public class Demo4001 {
    public void methodFu(){
        System.out.println("父类方法执行啦!");
    }
    public void method(){
        System.out.println("父类重名方法执行啦!");
    }
}

子类方法:

package cn.code;

public class Demo4002 extends Demo4001{
    public void methodZi(){
        System.out.println("子类方法执行啦!");
    }
    public void method(){
        System.out.println("子类重名方法执行啦!");
    }
}
13.6 继承中方法的覆盖重写
	重写(Override)

​ 概念:在继承关系当中,方法的名称一样,参数列表也一样。

​ 重写(Override): 方法的名称一样,参数列表【也一样】。 覆盖、覆写。
​ 重载(Overload): 方法的名称一样,参数列表【不一样】。
​ 方法的覆盖重写特点:创建的是子类对象,则优先使用子类方法。

方法覆盖重写的注意事项:

  1. 必须保证父子类之间方法的名称相同,参数列表也相同。

    @Override:写在方法前面,用来检测是不是有效的正确覆盖重写。

    这个注解就算是不写,只要满足要求,也是正确的方法覆盖重写。

    1. 子类方法的返回值必须【小于等于】父类方法的返回值范围。

    小拓展提示:java.lang.Object类是所有类的公共最高父类(祖宗类),java.lang.String就是Object的子类。

    1. 子类方法的权限必须【大于等于】父类方法的权限修饰。

    小扩展提示:public > protect > (default) > private

    备注:(default) 不是关键字default,而是什么都不写,留空。

13.7 继承中方法的覆盖重写

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-su1znmR8-1573821333461)(C:\Users\Think-Pad\Desktop\java\继承中方法的覆盖重写.jpg)]

main方法:

package cn.code;

public class Demo41 {
    public static void main(String[] args){
        Demo4102 dem = new Demo4102();
        dem.newff();  //  打电话  发短信  看视频
    }
}

父类:

package cn.code;
// 定义一个父类
public class Demo4101 {
    //  原有的功能
    //  定义方法
    public void call(){
        System.out.println("打电话");
    }
    public void sendMessage(){
        System.out.println("发短信");
    }
}

子类:

package cn.code;
//  定义一个子类
public class Demo4102 extends Demo4101{
    public void newff(){
        //  使用父类的方法用super
        super.call();
        super.sendMessage();
        System.out.println("看视频");

    }
}

13.8 继承中构造方法的访问特点

​ 继承关系中,父子类构造方法的访问特点:

  1. 子类构造方法当中有一个默认隐含的“super()”调用,所以一定是先调用的父类构造,后执行的子类构造。
  2. 子类构造可以通过super关键字来调用父类重载构造。
  3. super的父类构造调用,必须是子类构造方法的第一个语句。不能一个子类构造调用多次super构造。

总结:

子类必须调用父类构造方法不写则赠送super();写了则用写的指定的super调用,super只能有一个,还必须是第一个。

只有子类构造方法才能调用父类构造方法。

13.9 super关键字的三种用法

子类:

package cn.code;
/*
super关键字的用法有三种:
1. 在子类的成员方法中,访问父类的成员变量。
2. 在子类的成员方法中,访问父类的成员方法。
3. 在子类的构造方法中,访问父类的构造方法。
 */
public class Demo42 extends Demo4201{
    //  在子类的构造方法中,访问父类的构造方法。
    public Demo42(){
        super();
    }
    public void methodZi(){
        System.out.println(super.num);  //  访问父类的成员变量。
        super.method();  //  访问父类的成员方法。

    }
}

父类:

package cn.code;

public class Demo4201 {
    int  num = 845;
    public Demo4201(){
        System.out.println("中秋节快乐!");
    }
    public void method(){
        System.out.println("节日快乐!");
    }
}
13.10 this关键字的三种用法
package cn.code;
/*
super关键字用来访问父类内容,而this关键字用来访问本类内容。用法也有三种:
1. 在本类的成员方法中,访问本类的成员变量。
2. 在本类的成员方法中,访问本类的另一个成员方法。
3. 在本类的构造方法中,访问本类的另一个构造方法。
在第三种用法当中要注意:
A. this(...)调用也必须是构造方法的第一个个语句,唯一一个。
B. super和this两种构造调用,不能同时使用。
 */
public class Demo43 {
    int num = 666;

    public void showNum(){
        int num = 888;
        System.out.println(num);  //  调用局部变量
        System.out.println(this.num);  //   调用本类的成员变量
    }
    
    //  在本类的构造方法中,访问本类的另一个构造方法。
    public Demo43(){
        this(55);
        
    }
    public Demo43(int num){
    	this(4,5);
    }
    public Demo43(int a, int b)
}
13.11 super与this关键字图解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YYcuyEwB-1573821333463)(C:\Users\Think-Pad\Desktop\java\super与this关键字图解.jpg)]

13.12 继承的三个特点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sSdZ3rcZ-1573821333464)(C:\Users\Think-Pad\Desktop\java\继承的三个特点.jpg)]

第十四章 抽象

14.1 抽象的概念

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o4l3mJ0u-1573821333465)(C:\Users\Think-Pad\Desktop\java\抽象的概念.jpg)]

14.2 抽象方法和抽象类

main方法:

package cn.code;
/*
抽象方法:就是加上abstract关键字,然后去掉大括号,直接分号结束。
抽象类:抽象方法所在的类,必须是抽象类才行。在class之前写上abstract即可。

如何使用抽象类和抽象方法:
1. 不能直接创建new抽象类对象。
2. 必须用一个子类来继承抽象父类。
3. 子类必须覆盖重写抽象父类当中所有的抽象方法。
覆盖重写(实现):子类去掉抽象方法的abstract关键字,然后补上方法体大括号。
4. 创建子类对象进行使用。
 */
public class Demo44 {
    public static void main(String[] args) {
        Demo4402 deo = new Demo4402();
        deo.eat();  //  猫吃鱼
    }
}

抽象类:

package cn.code;

public abstract class Demo4401 {
    public abstract void eat();  //  定义一个抽象方法  用abstract关键字

}

子类:

package cn.code;

public class Demo4402 extends Demo4401{
    // 定义一个子类继承抽象类
    public void eat(){
        System.out.println("猫吃鱼");
    }
}
14.3 使用抽象类的注意事项:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dkR7Fzpx-1573821333467)(C:\Users\Think-Pad\Desktop\java\使用抽象类的注意事项.jpg)]

main方法:

package cn.code;

public class Demo45 {
    public static void main(String[] args) {
        Demo4503 dem = new Demo4503();
        dem.eat();  //  狗吃骨头
        dem.sleep();  //  呼呼呼
    }
}

最高级抽象类:

package cn.code;
//  创建一个最高级抽象类
public abstract class Demo4501 {
    public abstract void eat();
    public abstract void sleep();

}

子抽象类:

package cn.code;
//  创建一个子抽象类
public abstract class Demo4502 extends Demo4501 {
    @Override
    public void eat(){
        System.out.println("狗吃骨头");

        //  public abstract void sleep();
    }
}

子类:

package cn.code;
//  建立一个子类
public class Demo4503 extends Demo4502{
    @Override
    public void sleep(){
        System.out.println("呼呼呼");
    }
}
14.4 发红包案例

main方法:

package cn.code.Demo01;

import java.util.ArrayList;

public class mainRedPacket {
    public static void main(String[] args) {
        Manager manager = new Manager("群主",100);

        Member one = new Member("成员A",0);
        Member two = new Member("成员B",0);
        Member three = new Member("成员C",0);

        manager.show();
        one.show();
        two.show();
        three.show();
        System.out.println("================");

        //  群主发红包,20元3包
        ArrayList<Integer> redlist = manager.send(20,3);
        //  三个普通成员收红包
        one.recive(redlist);
        two.recive(redlist);
        three.recive(redlist);

        //  显示各自余额
        manager.show();
        one.show();
        two.show();
        three.show();
/*      运行结果:
        我叫:群主,我有 100
        我叫:成员A,我有 0
        我叫:成员B,我有 0
        我叫:成员C,我有 0
                ================
        我叫:群主,我有 80
        我叫:成员A,我有 8
        我叫:成员B,我有 6
        我叫:成员C,我有 6*/
    }

}

用户类:

package cn.code.Demo01;

public class User {
    private String name;  //  姓名
    private int money;  //  余额,也就是当前用户拥有的钱数

    public User() {
    }

    public User(String name, int money) {
        this.name = name;
        this.money = money;
    }
    //  展示一下用户有多少钱
    public void show(){
        System.out.println("我叫:"+ name + ",我有 " + money);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }
}

群主类:

package cn.code.Demo01;

import java.util.ArrayList;

//  群主
public class Manager extends User {
    public Manager() {
    }

    public Manager(String name, int money) {
        super(name, money);
    }

    //  定义一个方法用来表示群主发红包
    public ArrayList<Integer> send(int totalMonney, int count){
        //  首先要有一个集合用来存储若干个红包的金额
        ArrayList<Integer> redList = new ArrayList<>();

        //  看一下群主有多少钱  进行判断
        int leftMoney = super.getMoney();  // 群主余额
        if (leftMoney < totalMonney ){
            System.out.println("余额不足!");
            return redList;  //  返回空集合
        }

        //  扣钱,其实就是重新设置余额
        super.setMoney(leftMoney - totalMonney);

        //  发红包需要平均分成count份
        int avg = totalMonney / count;
        int mod = totalMonney % count;   //  余数,也就是甩下的零头

        //  除不开的零头,包在最后一个包中
        // 下面把红包一个一个放到集合中
        for (int i = 0; i < count - 1; i++) {
            redList.add(avg);
        }

        //  最后一个红包
        int last = avg + mod;
        redList.add(last);
        return redList;

    }

}

成员类:

package cn.code.Demo01;

import java.util.ArrayList;
import java.util.Random;

//  成员类
public class Member extends User {
    public Member() {
    }

    public Member(String name, int money) {
        super(name, money);
    }

    //  定义一个方法表示成员收红包
    public void recive(ArrayList<Integer> list){
         //  从多个红包中随机抽取一个给我自己
         //  随机获取一个集合当中的索引编号
        int index = new Random().nextInt(list.size());
        //  根据索引,从集合中删除,并且得到被删除的红包,留给自己
        int d = list.remove(index);
        //  当前成员本来有多少钱
        int money = super.getMoney();
        //  加法,并且重新设置回去
        super.setMoney(money + d );
    }
}

第十五章 接口

15.1 接口的定义基本格式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ns8A2hiQ-1573821333469)(C:\Users\Think-Pad\Desktop\java\接口.jpg)]

​ 接口就是多个类的公共规范。

接口是一种引用数据类型,最重要的内容就是其中的 – 抽象方法。

​ 如何定义一个接口的格式:

​ public interface 接口名称{

​ // 接口内容

​ }

备注:换成了关键字interface之后,编译生成的字节码文件仍然是:.java --> .class

​ 如果是Java7. 那么接口中可以包含的内容有:

  1. 常量
  2. 抽象方法

​ 如果是 Java 8. 还可以额外包含有:

  1. 默认方法

  2. 静态方法

    如果是 Java9. 还可以额外包含有:

    1. 私有方法
15.2 接口的抽象方法定义

接口:

package cn.code.Demo002;
/*
在任何版本的Java中,接口都能定义抽象方法。
格式:
public abstract 返回值类型 方法名称(参数列表);

注意事项:
1. 接口当中的抽象方法,修饰符必须是两个固定的关键字: public abstract
2. 这两个关键字修饰符,可以选择性的省略。
3. 方法的三要素,可以随意定义。
 */
public interface MyInterFaceAbstract {
    //  以下均为抽象方法,都正确
    public abstract void methodA();
    abstract void methodB();
    public  void methodC();
    void methodD();
}

继承接口:

package cn.code.Demo002;

public class MyInterFaceAbstractImpl implements MyInterFaceAbstract{

    @Override
    public void methodA() {
        System.out.println("这是第一个方法!");
    }

    @Override
    public void methodB() {
        System.out.println("这是第二个方法!");
    }

    @Override
    public void methodC() {
        System.out.println("这是第三个方法!");
    }

    @Override
    public void methodD() {
        System.out.println("这是第四个方法!");
    }
}

main方法:

package cn.code.Demo002;
/*
接口使用步骤:
1. 接口不能直接使用,必须有一个“实现类”来“实现”该接口。
格式:
public class 实现类名称 implements 接口名称{
    //  ...
}
2. 接口的实现类必须覆盖重写(实现)接口中所有的抽象方法。
实现:去掉abstract关键字,加上方法体大括号。
3. 创建实现类的对象,进行使用。

注意事项:
如果实现类没有覆盖重写接口中所有的抽象方法,那么这个实现类自己就必须是抽象类。
 */
public class Interface {
    public static void main(String[] args) {

     /*   MyInterFaceAbstract inter = new MyInterFaceAbstract() {
        }*/   // 错误写法

        MyInterFaceAbstractImpl abs = new MyInterFaceAbstractImpl();
        abs.methodA();  //  这是第一个方法!
        abs.methodC();  //  这是第三个方法!
    }
}
15.3 接口的默认方法

接口:

package cn.code.Demo002;
/*
从Java 8 开始,接口里允许定义默认方法。
格式:
public default 返回值类型 方法名称(参数列表){
        方法体
}

备注:接口当中的默认方法,可以解决接口升级的问题。
 */
public interface MyInterfaceDefult {
    //  这是一个抽象方法
    public abstract void methodAbs1();
    //  新添一个抽象方法  后面的继承类会报错
//    public abstract void methodAbs2();

    //  这是一个默认方法
    public default void methodDefault(){
        System.out.println("默认方法执行啦!");
    }

}

实现类A:

package cn.code.Demo002;

public class MyInterfaceDefaultA implements MyInterfaceDefult{

    @Override
    public void methodAbs1() {
        System.out.println("实现了抽象方法:AAA");

    }
}

实现类B:

package cn.code.Demo002;

public class MyInterfaceDefaultB implements MyInterfaceDefult{

    @Override
    public void methodAbs1() {
        System.out.println("实现了抽象方法:BBB");

    }

    public void methodDefault(){
        System.out.println("实现了B的覆盖重写");
    }
}

main方法:

package cn.code.Demo002;
/*
1. 接口的默认方法,可以通过接口实现类对象,直接调用。
2. 接口的默认方法,也可以被接口实现类进行覆盖重写。
 */
public class InterfaceDefault {
    public static void main(String[] args) {
        MyInterfaceDefaultA a = new MyInterfaceDefaultA();
        a.methodAbs1();  //  实现了抽象方法:AAA        调用抽象方法,实际运行的是右侧实现类。
        a.methodDefault();  //  默认方法执行啦!        调用默认方法,如果实现类当中没有,会向上找接口。

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


        MyInterfaceDefaultB b = new MyInterfaceDefaultB();
        b.methodAbs1();  //  实现了抽象方法:BBB
        b.methodDefault();  //  实现了B的覆盖重写
    }
}
15.4 接口的静态方法

接口:

package cn.code.Demo002;
/*
从Java 8 开始,接口当中允许定义静态方法。
格式:
public static 返回值类型 方法名称(参数列表){
    方法体
}
提示:就是将abstract或者default换成static即可,带上方法体。
 */
public interface MyInterfaceStatic {
    public static void method(){
        System.out.println("这是一个接口的静态方法!");
    }
}

实现类:

package cn.code.Demo002;

public class MyInterfaceStaticImpl implements MyInterfaceStatic {
}

main方法:

package cn.code.Demo002;
/*
注意:不能通过接口实现类的对象来调用接口当中的静态方法。
正确用法:通过接口名称,直接调用其中的静态方法。
格式:
接口名称.静态方法名(参数);
 */
public class InterfaceStatic  {
    public static void main(String[] args) {
        MyInterfaceStaticImpl inter = new MyInterfaceStaticImpl();
//        inter.method;     //  错误写法!

        //  直接通过接口名称来调用静态方法
        MyInterfaceStatic.method();  //  这是一个接口的静态方法!
    }

}
15.5 接口的私有方法

接口:

package cn.code.Demo002;
/*
问题描述:
我们需要抽取一个共有方法,用来解决两个默认方法之间重复代码的问题。
但是这个共有方法不应该让实现类使用,应该是私有化的。

解决方案:
从Java 9 开始,接口当中允许定义私有方法。
1. 普通私有方法,解决多个默认方法之间重复代码问题
格式:
private 返回值类型 方法名称(参数列表){
    方法体
}

2. 静态私有方法,解决多个静态方法之间重复代码问题
格式:
private static 返回值类型 方法名称(参数列表){
    方法体
}
 */
public interface MyInterfacePrivate {
    public default void methodDefault1(){
        System.out.println("默认方法1");
        methodCommon();
    }
    public default void methodDefault2(){
        System.out.println("默认方法2");
        methodCommon();
    }
    public default void methodCommon(){
        System.out.println("aaaaaaaa");
        System.out.println("bbbbbbbb");
        System.out.println("cccccccc");
/*    private void methodCommon(){
        System.out.println("aaaaaaaa");
        System.out.println("bbbbbbbb");
        System.out.println("cccccccc");
*/

    }

}

实现类:

package cn.code.Demo002;

public class MyInterfacePrivateImpl implements MyInterfacePrivate {
    public void methodAnother(){
        //  直接访问到了接口中的默认方法,这是错误的!
//       methodCommon();
    }
}
15.6 接口的常量定义和使用

接口:

package cn.code.Demo002;
/*
接口当中可以定义“成员变量”,但是必须使用public static final三个关键字进行修饰。
从效果上看,这其实就是接口的【常量】。
格式:
public static final 数据类型 常量名称 = 数据值;
备注:
一旦使用final关键字进行修饰,说明不可改变。

注意事项:
1. 接口当中的常量,可以省略public static final,注意:不写也照样是这样。
2. 接口当中的常量,必须进行赋值,不能不赋值。
3. 接口中常量的名称,使用完全大写字母,用下划线进行分割。(推荐命名规则)
 */
public interface MyInterfaceConst {
    public static final int A = 45;
}

main方法:

package cn.code.Demo002;

public class InterfaceConst {
    public static void main(String[] args) {
        System.out.println(MyInterfaceConst.A);  //  45
    }
}
15.7 接口的内容小结

​ 在Java 9+ 版本中,接口的内容可以有:

  1. 成员变量其实是常量,格式:

    [public] [static] [final] 数据类型 常量名称 = 数据值;

    注意:

    ​ 常量必须进行赋值,而且一旦赋值不能改变。

    ​ 常量名称完全大写,用下划线进行分割。

    1. 接口中最重要的就是抽象方法,格式:

    [public] [abstract] 返回值类型 方法名称(参数列表);

    注意:实现类必须覆盖重写接口所有的抽象方法,除非实现类是抽象类。

    1. 从Java 8 开始,接口里允许定义默认方法,格式:

    [public] defult 返回值类型 方法名称(参数列表){方法体}

    注意:默认方法也可以被覆盖重写

    1. 从Java 8 开始,接口里允许定义静态方法,格式:

    [public] static 返回值类型 方法名称(参数类型){方法体}

    注意:应该通过接口名称进行调用,不能通过实现类对象调用接口静态方法

    1. 从Java 9 开始,接口里允许定义私有方法,格式:

    普通私有方法:private 返回值类型 方法名称(参数列表){方法体}

    静态私有方法:private static 返回值类型 方法名称(参数列表){方法体}

    注意:private的方法只有接口自己才能调用,不能被实现类或别人使用。

15.8 继承父类并实现多个接口

​ 使用接口的时候,需要注意:

  1. 接口是没有静态代码块或者构造方法的。

  2. 一个类的直接父类是唯一的,但是一个类可以同时实现多个接口。

    格式:

    public class MyInterfaceImpl implement MyInterfaceA,MyInterfaceB{

    ​ // 覆盖重写所有抽象方法

    }

    1. 如果实现类所有实现的多个接口当中,存在重复的抽象方法,那么只需要覆盖重写一次即可。
    2. 如果实现类没有覆盖重写所有接口当中的所有抽象方法,那么实现类就必须是一个抽象类。
    3. 如果实现类所实现的多个接口当中,存在重复的默认方法,那么实现类一定要对冲突的默认方法进行覆盖重写。
    4. 一个类如果直接父类当中的方法,和接口当中的默认方法产生了冲突,优先用父类当中的方法。
15.9 接口之间的多继承
  1. 类与类之间是单继承的,直接父类只有一个。
  2. 类与接口之间是多实现的。一个类可以实现多个接口。
  3. 接口与接口之间是多继承的。

注意事项:

  1. 多个父接口当中的抽象方法如果重复,没关系。
  2. 多个父接口当中的默认方法如果重复,那么子接口必须进行默认方法的覆盖重写,【而且带着default关键字】。

第十六章 多态

16.1 多态的概念

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H5en4Z6t-1573821333471)(C:\Users\Think-Pad\Desktop\java\多态.jpg)]

16.2 多态的格式与使用

main方法:

package cn.code.Demo003;
/*
代码当中体现多态性,其实就是一句话:父类引用指向子类对象。

格式:
父类名称  对象名 = new 子类名称();
或者:
接口名称  对象名 = new 实现类名称();

 */
public class Demo01Multi {
    public static void main(String[] args) {
        //  使用多态的写法
        //  左侧父类的引用,指向了右侧子类的对象
        Fu obj = new Zi();
        obj.method();  //  子类方法!
        obj.methodFu();  //  父类特有方法!
    }
}

父类:

package cn.code.Demo003;

public class Fu {
    public void method(){
        System.out.println("父类方法!");
    }
    public void methodFu(){
        System.out.println("父类特有方法!");
    }
}

子类:

package cn.code.Demo003;

public class Zi extends Fu {
    @Override
    public void method() {
        System.out.println("子类方法!");
    }
}
16.3 多态中成员变量的使用特点

父类:

package cn.code.Demo004;

public class Fu /*extends Object*/ {
    int num = 45;

    public void method(){
        System.out.println(num);
    }

}

子类:

package cn.code.Demo004;

public class Zi extends Fu {
    int num = 85;

    @Override
    public void method() {
        System.out.println(num);
    }
}

main方法:

package cn.code.Demo004;
/*
访问成员变量的两种方式:

1. 直接通过对象名称访问成员变量:看等号左边是谁,优先用谁,没有则向上找。
2. 间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找。
 */
public class MultiField {
    public static void main(String[] args) {
        //  使用多态的写法,父类引用指向子类对象
        Fu obj = new Zi();
        System.out.println(obj.num);  //  45
//        System.out.println(obj.age);  //  错误写法
        System.out.println("=====================");

        //  子类没有覆盖重写,就是父:45
        //  子类覆盖重写,就是子:85
        obj.method();
    }

}
16.4 多态中成员方法的使用特点

父类:

package cn.code.Demo004;

public class Fu /*extends Object*/ {
   public void method(){
       System.out.println("父类方法!");
   }
    public void methodFu(){
        System.out.println("父类特有方法!");
    }
}

子类:

package cn.code.Demo004;

public class Zi extends Fu {
    @Override
    public void method() {
        System.out.println("子类方法!");
    }
}

main方法:

package cn.code.Demo004;
/*
在多态的代码当中,成员方法的访问规则是:
    看new的谁,就优先用谁,没有则向上找。

口诀:编译看左边,运行看右边。

对比一下:
成员变量:编译看左边,运行看左边。
成员方法:编译看左边,运行看右边。
 */
public class MultiMethod {
    public static void main(String[] args) {
        Fu obj = new Zi();  //  多态
        obj.method();  //  子类方法!      父子都有,优先用子
        obj.methodFu();  //  父类特有方法!        子类没有,父类有,向上找到父类
  //    obj.methodZi();  //  错误写法
    }
}
16.5 使用多态的好处

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d3bb6sMC-1573821333472)(C:\Users\Think-Pad\Desktop\java\使用多态的好处.jpg)]

16.6 对象的向上转型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-njIzC7cu-1573821333474)(C:\Users\Think-Pad\Desktop\java\对象的向上转型.jpg)]

抽象类:

package cn.code.Demo004;
//  定义一个抽象类
public abstract class Animal {
    public void eat(){};
}

实现类:

package cn.code.Demo004;
//  实现抽象类
public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼!");
    }
}

main方法:

package cn.code.Demo004;

public class Demo01Main {
    public static void main(String[] args) {
        //  对象的向上转型,就是:父类引用指向子类对象。
        Animal animal = new Cat();
        animal.eat();  //  猫吃鱼!
    }
}
16.7 对象的向下转型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z9tcb6IX-1573821333475)(C:\Users\Think-Pad\Desktop\java\对象的向下转型.jpg)]

main方法:

package cn.code.Demo004;
/*
向上转型一定是安全的,没有问题的,正确的。但是也有一个弊端:
对象一旦向上转型为父类,那么久无法调用子类原本特有的内容。

解决方案:用对象的向下转型【还原】。
 */
public class Demo01Main {
    public static void main(String[] args) {
        //  对象的向上转型,就是:父类引用指向子类对象。
        Animal animal = new Cat();
        animal.eat();  //  猫吃鱼!

//        animal.CatchMouse();      //  错误写法!

        //  向下转型,进行“还原”动作
        Cat cat = (Cat)animal;
        ((Cat) animal).CatchMouse();  //  猫抓老鼠!

        //  下面是错误的向下转型
        //  本来new的时候是一只猫,现在非要当做狗
//        Dog dog = (Dog)animal;  //  java.lang.ClassCastException  类型转换异    编译器不报错,运行报错


    }
}

抽象类:

package cn.code.Demo004;
//  定义一个抽象类
public abstract class Animal {
    public void eat(){};
}

实现类:

package cn.code.Demo004;
//  实现抽象类
public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼!");
    }
    public void  CatchMouse(){
        System.out.println("猫抓老鼠!");
    }
}
package cn.code.Demo004;

public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃骨头!");
    }
}
16.8 用instanceof关键字进行联系判断

抽象类:

package cn.code.Demo004;
//  定义一个抽象类
public abstract class Animal {
    public void eat(){};
}

实现类:

package cn.code.Demo004;
//  实现抽象类
public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼!");
    }
    public void  CatchMouse(){
        System.out.println("猫抓老鼠!");
    }
}
package cn.code.Demo004;

public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃骨头!");
    }
    public void CatchHouse(){
        System.out.println("狗看家!");
    }
}

main方法:

package cn.code.Demo004;
/*
如何才知道一个父类引用的对象,本来是什么子类?
格式:
对象  instanceof  类名称
这将会得到一个Boolean值结果,也就是判断前面对象能不能当做后面类型的实例。
 */
public class Demo02Instanceof {
    public static void main(String[] args) {
        Animal animal = new Dog();
        animal.eat();  //  狗吃骨头!
        // 如果希望调用子类的特有方法,需要向下转型
        // 判断一下父类引用animal本来是不是Dog

        if (animal instanceof Dog){
            Dog dog = (Dog)animal;
            dog.CatchHouse();  //  狗看家!
        }
        if (animal instanceof Cat){
            Cat cat = (Cat)animal;
            cat.CatchMouse();
        }
    }
}
16.9 笔记本USB接口案例

main方法:

package cn.code.Demo005;

public class DemoMain {
    public static void main(String[] args) {
        //  首先创建一个笔记本电脑
        Computer computer = new Computer();
        computer.powerOn();

        //  准备一个鼠标,供电脑使用
//        Mouse mouse = new Mouse();
        //  首先进行向上转型
        USB usbMouse = new Mouse();  //  多态方法
        //  参数是USB类型,我正好传递进去的就是USB鼠标
        computer.usbDevice(usbMouse);

        //  创建一个USB键盘
        Keyboard keyboard = new Keyboard();  //  没有使用多态写法
        //  方法参数是USB类型,传递进去的是实现类对象
        computer.usbDevice(keyboard);  //  正确写法!

        computer.powerOff();


    }
}

USB接口:

package cn.code.Demo005;

public interface USB {
    public abstract void open();
    public abstract void close();
}

实现类:

package cn.code.Demo005;

public class Computer {
    public void powerOn(){
        System.out.println("笔记本电脑开机");
    }
    public void powerOff(){
        System.out.println("笔记本电脑关机");
    }

    //  使用USB设备的方法,使用接口作为方法的参数
    public void usbDevice(USB usb){
        usb.open();  //  打开设备
        if (usb instanceof Mouse){
            Mouse mouse = (Mouse)usb;  //  向下转型
            mouse.click();
        }
        else if (usb instanceof Keyboard){
            Keyboard keyboard = (Keyboard)usb;
            keyboard.type();
        }
        usb.close();  //  关闭设备
    }
}
package cn.code.Demo005;
//  鼠标就是一个USB设备

public class Mouse implements USB {
    @Override
    public void open() {
        System.out.println("打开鼠标");
    }

    @Override
    public void close() {
        System.out.println("关闭鼠标");
    }
    public void click(){
        System.out.println("点击鼠标");
    }
}
package cn.code.Demo005;
//  键盘就是一个USB设备
import cn.code.Demo01.User;

public class Keyboard implements USB {
    @Override
    public void open() {
        System.out.println("打开键盘");
    }

    @Override
    public void close() {
        System.out.println("关闭键盘");
    }
    public void type(){
        System.out.println("键盘输入");
    }
}

第十七章 final关键字

final关键字代表最终、不可改变的。

常见的四种方法:

  1. 可以用来修饰一个类
  2. 可以用来修饰一个方法
  3. 还可以用来修饰一个局部变量
  4. 还可以用来修饰一个成员变量
17.1 final关键字用于修饰类

final类:

package cn.code.Demo006;
/*
当final关键字用来修饰一个类的时候,格式:
public final class 类名称{
    //  ...
}

含义:当前这个类不能有任何子类。(太监类)
注意:一个类如果是final的,那么其中所有的成员方法都无法进行覆盖重写(因为没儿子)。
 */
public final  class Myclass /*extends Object */ {

    public void  method(){
        System.out.println("方法执行!");
    }
}

继承类:

package cn.code.Demo006;
/*
不能使用一个final类来作为父类
 */
public class MySubClass /*extends Myclass*/ {

}
17.2 final关键字用于修饰成员方法

父类:

package cn.code.Demo006;
/*
当final关键字用来修饰一个方法的时候,这个方法就是最终方法,也就是不能被覆盖重写。
格式:
修饰符 final 返回值类型 方法名称(参数列表){
    //  方法体
}

注意事项:
对于类、方法来说,abstract关键字和final关键字不能同时使用,因为没矛盾。
 */
public class Fu {
    public final void methodFu(){
        System.out.println("父方法执行!");

    }
    public/* final abstract*/ void method(){
        System.out.println("======");
    }
}

子类:

package cn.code.Demo006;

public class Zi extends Fu {
    //  报错
    /*@Override
    public void methodFu() {
        System.out.println("子类方法执行!");
    }*/
}
17.3 final关键字用于修饰局部变量

final类:

package cn.code.Demo006;

public class Demo01Final {
    public static void main(String[] args) {
        int num = 15;
        System.out.println(num);  //  15
        num = 65;
        System.out.println(num);  //  65

        //  一旦使用final用来修饰局部变量,那么这个变量就不能进行更改。
        //  “一次赋值,终生不变”
        final int num1 = 68;
        System.out.println(num1);
//        num1 = 56;  //  错误写法

        //  正确写法!只要保证有唯一一次赋值即可
        final int num3;
        num3 =653;

        //  对于基本类型来说,不可变说的是变量当中的数据不可改变
        //  对于引用类型来说,不可变说的是变量当中的地址值不可改变
        Student student1 = new Student("周杰伦");
        System.out.println(student1);  //  cn.code.Demo006.Student@4554617c
        System.out.println(student1.getName());  //  周杰伦

        student1 = new Student("五月天");
        System.out.println(student1);
        System.out.println(student1.getName());  //  五月天


        final Student student2 = new Student("阿信");
        //  错误写法!final的引用类型变量,其中的地址值不可改变。
//        student2 = new Student("陈绮贞");

        System.out.println(student2.getName());  //  阿信
        student2.setName("陈奕迅"); 
        System.out.println(student2.getName());  //  陈奕迅
    }
}

student类:

package cn.code.Demo006;

public class Student {
    private String name;
     public Student() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Student(String name) {
        this.name = name;
    }
}
17.4 final关键字用于修饰成员变量
package cn.code.Demo006;
/*
对于成员变量来说,如果使用final关键字,那么这个变量也照样是不可变的。

1. 由于成员变量具有默认值,所以用了final之后必须手动赋值,不会再给默认值了。
2. 对于final的成员变量,要么使用直接赋值,要么通过构造方法赋值。二者选其一。
3. 必须保证类当中所有重载的构造方法,都最终会对final的成员变量进行赋值。
 */
public class Person {
    private final String name /*= "鹿晗"*/;

    public Person() {
        name = "关晓彤 ";
    }

    public String getName() {
        return name;
    }

   /* public void setName(String name) {
        this.name = name;
    }*/

    public Person(String name) {
        this.name = name;
    }
}
17.5 四种权限修饰符

java中有四种权限修饰符:
                        public   >  protected  >  (default)  >  private
同一个类(我自己)           YES         YES             YES         YES
同一个包(我邻居)           YES         YES             YES         NO
不同包子类(我儿子)          YES         YES             NO          NO
不同包非子类(陌生人)         YES         NO              NO          NO

注意事项:(default)并不是关键字“default”,而是根本不写。

第十八章 内部类

18.1 成员内部类的定义

package cn.code.Drmo007;
/*
如果一个事物的内部包含一个事物,那么这就是一个类内部包含另一个类。
例如:身体和心脏的关系。又如:汽车和发动机的关系。

分类:
1. 成员内部类
2. 局部内部类(包含匿名内部类)

成员内部类的定义格式:
修饰符 class 外部类名称{
    修饰符 class 内部类名称{
        // ...
    }
    // ...
}

注意:内用外,随意访问,需要内部类对象。
 */
public class Demo01InnerClass { //  外部类
    //  外部的成员变量
    private String name;  
    public void method(){
        System.out.println("外部类的方法!");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    //  成员内部类
    public class Heart{
        public void beat(){  //  成员内部类的方法
            System.out.println("我叫" + name);
            System.out.println("心脏跳动!");
        }
    }
}
18.2 成员内部类的使用

main方法:

package cn.code.Drmo007;
/*
如何使用成员内部类?有两种方式:
1. 间接方式:在外部类的方法当中,使用内部类;然后main只是调用外部类的方法。
2. 直接方式:公式:
类名称 对象名 = new 类名称();
【外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();】
 */
public class Demo02InnerClass {
    public static void main(String[] args) {
        Demo01InnerClass dem = new Demo01InnerClass();
        dem.method();
       /* 外部类的方法!
        我叫null
        心脏跳动!*/

       

    }
}
public class Demo01InnerClass { //  外部类
    //  外部的成员变量
    private String name;
    public void method(){
        System.out.println("外部类的方法!");
        Heart heart = new Heart();
        heart.beat();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    //  成员内部类
    public class Heart{
        public void beat(){  //  成员内部类的方法
            System.out.println("我叫" + name);
            System.out.println("心脏跳动!");
        }
    }
}
18.3 内部类的同名变量访问
package cn.code.Drmo007;
/*
如果出现了重名现象,那么格式是:外部类名称.this.内部类成员变量名
 */
public class Outer {
    int num = 45;  //  外部类的成员变量

    public class Inner /*extends Object*/ {
        int num = 89;  //  内部类的成员变量

        public void methodInner(){
            int num = 652;  //  内部方法的局部变量
            System.out.println(num);  //  内部方法的局部变量,就近原则
            System.out.println(this.num);  //  内部类的成员变量
            System.out.println(Outer.this.num);  //   外部类的成员变量
        }
    }
}
18.4 局部内部类
package cn.code.Drmo007;
/*
如果一个类是定义在一个方法内部的,那么这就是一个局部内部类。
“局部”:只有当前所属的方法才能使用它,出了这个方法外面就不能用了。

定义格式:
修饰符 class 外部类名称 {
    修饰符  返回值类型  外部类名称(参数列表){
            class  局部内部类名称{
                //  ...
            }
    }
}

小结一下类的权限修饰符:
public > protectde > (default) > private
定义一个类的时候,权限修饰符规则:
1. 外部类:public / (default)
2. 成员内部类:public / protectde / (default) / private
3. 局部内部类:什么都不写
 */
public class Outer01 {
    public void methodOuter(){
        class Inner{
            public void methodInner(){
                System.out.println("奇妙能力歌");
            }
        }
        Inner inner = new Inner();
        inner.methodInner();
    }
}
18.5 局部内部类的final问题
package cn.code.Drmo007;
/*
局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是【有效final的】。

备注:从Java 8+ 开始,只要局部变量事实不变,那么final关键字可以省略。

原因:
1. new出来的对象在堆内存当中。
2. 局部变量是跟着方法走的,在栈内存当中。
3. 方法运行结束之后,立刻出栈,局部变量就会立刻消失。
4. 但是new出来的对象会在堆当中持续存在,直到垃圾回收消失。
 */
public class MyOuter {
    public void methodOuter(){
       final int num = 845;
        
        class Inner{
            public void methodInner(){
                System.out.println(num);
            }    
        }
    }
}
18.6 匿名内部类

接口:

package cn.code.Drmo007;

public interface MyInterface {
    public abstract void method();
}

main方法:

package cn.code.Drmo007;
/*
如果接口实现类(或者是父类的子类)只需要使用一次,
那么这种情况下就可以省略掉该类的定义,而改为使用【匿名内部类】。

匿名内部类的定义格式:
接口名称  对象名  = new 接口名称(){
    //  覆盖重写所有抽象方法
};
 */
public class DemoMain {
    public static void main(String[] args) {
        //  使用匿名内部类
        MyInterface obj = new MyInterface() {
            @Override
            public void method() {
                System.out.println("匿名内部类实现了方法!");
            }
        };
        obj.method();  //  匿名内部类实现了方法!
    }
}
18.7 匿名内部类的注意事项

接口:

package cn.code.Drmo007;

public interface MyInterface {
    public abstract void method1();
    public abstract void method2();
}

main方法:

package cn.code.Drmo007;
/*
如果接口实现类(或者是父类的子类)只需要使用一次,
那么这种情况下就可以省略掉该类的定义,而改为使用【匿名内部类】。

匿名内部类的定义格式:
接口名称  对象名  = new 接口名称(){
    //  覆盖重写所有抽象方法
};

对格式“new 接口名称(){...}”进行解析:
1. new代表创建对象的动作
2. 接口名称就是匿名内部类需要实现哪个接口
3. {...}这才是匿名内部类的内容

另外还要注意几点问题:
1. 匿名内部类,在【创建对象】的时候,只能使用唯一一次。
如果希望多次创建对象,而且类的内容一样的话,那么就必须使用单独定义的实现类了。
2. 匿名对象,在【调用方法】的时候,只能调用唯一一次。
如果希望同一个对象,调用多次方法,那么必须给对象起个名字。
3. 匿名内部类是省略了【实现类/子类名称】,但是匿名对象是省略了【对象名称】
强调:匿名内部类和匿名对象不是一回事!!!
 */
public class DemoMain {
    public static void main(String[] args) {
        //  使用匿名内部类,但不是匿名对象,对象名称就叫objA
        MyInterface objA = new MyInterface() {
            @Override
            public void method1() {
                System.out.println("匿名内部类实现了方法!111-A");
            }

            @Override
            public void method2() {
                System.out.println("匿名内部类实现了方法!222-A");
            }
        };
        objA.method1();
        objA.method2();

        //  使用了匿名内部类,而且省略了对象名称,也是匿名对象
        new MyInterface() {
            @Override
            public void method1() {
                System.out.println("匿名内部类实现了方法!111-B");
            }

            @Override
            public void method2() {
                System.out.println("匿名内部类实现了方法!222-B");
            }
        }.method1();
        //  因为匿名对象 无法调用第二次方法,所以需要再创建一个匿名内部类的匿名对象
        new MyInterface() {
            @Override
            public void method1() {
                System.out.println("匿名内部类实现了方法!111-B");
            }

            @Override
            public void method2() {
                System.out.println("匿名内部类实现了方法!222-B");
            }
        }.method2();
    }
}
18.8 类作为成员变量类型
package cn.code.Drmo007;
//  游戏当中的英雄角色类
public class Hero {

    private String name;  //  英雄的名字
    private int age;  //  英雄的年龄
    private Weapon weapon;  //  英雄的武器

    public Hero(String name, int age, Weapon weapon) {
        this.name = name;
        this.age = age;
        this.weapon = weapon;
    }

    public void attack(){
        System.out.println("年龄为" + age + "的" + name + "拿着" + weapon.getCode() + "去攻击敌人!");
    }

    public Hero(String name) {
        this.name = name;
    }

    public Hero() {
    }

    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 Weapon getWeapon() {
        return weapon;
    }

    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }
}
package cn.code.Drmo007;

public class Weapon {
    private String code;  //  武器的代号


    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public Weapon(String code) {
        this.code = code;
    }

    public Weapon() {
    }
}
package cn.code.Drmo007;

public class DemoMain01 {
    public static void main(String[] args) {
        //  创建一个英雄角色
        Hero hero = new Hero();
        //  为英雄角色设置名字和年龄
        hero.setName("亚瑟");
        hero.setAge(100);
        // 创建一个武器对象
        Weapon weapon = new Weapon("M24");

        // 为英雄配武器装备
        hero.setWeapon(weapon);

        hero.attack();  //  年龄为100的亚瑟拿着M24去攻击敌人!

    }
}
18.9 接口作为成员变量类型

接口:

package cn.code.Drmo007;

public interface Skill {
    void use();  //  释放技能的抽象方法
}

package cn.code.Drmo007;

public class Hero01 {
    private String name;  //  英雄的名称
    private Skill skill;  //  英雄的技能

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void attack(){
        System.out.println("我叫" + name + ",开始释放技能" );
        skill.use();
        System.out.println("释放技能完毕!");
    }

    public Skill getSkill() {
        return skill;
    }

    public void setSkill(Skill skill) {
        this.skill = skill;
    }

    public Hero01(String name) {
        this.name = name;
    }

    public Hero01() {
    }
}

main方法:

package cn.code.Drmo007;

public class DemoMain02 {
    public static void main(String[] args) {
        Hero01 hero01 = new Hero01();
        hero01.setName("孙尚香");  //  设置英雄名称

        //  设置英雄技能      可以单独定义实现类
        //  也可以改成使用匿名内部类

      /*  Skill skill = new Skill() {
            @Override
            public void use() {
                System.out.println("jiu~jiu~jiu");
            }
        };
        hero01.setSkill(skill);
        hero01.attack();*/

      //  进一步简化,同时使用匿名内部类和匿名对象
       hero01.setSkill(new Skill() {
           @Override
           public void use() {
               System.out.println("jiu~~~");
           }
       });
       hero01.attack();
       /*
        我叫孙尚香,开始释放技能
        jiu~~~
        释放技能完毕!
        */
    }
}
18.10 接口作为方法的参数和或返回值
package cn.code.Drmo007;

import java.util.ArrayList;
import java.util.List;
/*
java.util.List正是ArrayList所实现的接口。
 */
public class DemoMain03 {
    public static void main(String[] args) {
        // 左边是接口名称,右边是实现类名称,这就是多态写法
        List<String> list = new ArrayList<>();

        List<String> result = addNames(list);
        for (int i = 0; i < result.size(); i++) {
            System.out.println(result.get(i));
        }

        }
    public static List<String> addNames(List<String> list){
        list.add("迪丽热巴");
        list.add("古力娜扎");
        list.add("马尔扎哈");
        list.add("欧阳娜娜");
        return list;
    }
}

第十九章 Object类

19.1 Object类的toString方法
package cn.code.Drmo007.Demo008;


import javafx.scene.transform.Scale;

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

/*
    java.lang.Object
    类Object是层次结构的根(父)类。
    每个类(Person,Student...)都使用Object作为超(父)类。
    所有对象(包括数组)都实现这个类的方法。
 */
public class Demo01ToString {
    public static void main(String[] args) {
        /*
        Person类默认继承了Object类,所以可以使用Object类当中的toString方法
        String toString() 返回该对象的字符串表示。
         */
        Person person = new Person("陈粒",18);
        String s = person.toString();
        System.out.println(s);

        //  直接打印对象的名字,其实就是调用对象的toString   person = person.toString();
        System.out.println(person);
        //  看一个类是否重写了toString,直接打印这个类的对象即可,如果没有重写toString方法那么打印的是对象的地址值
        Random r= new Random();
        System.out.println(r);  //  地址值


        Scanner sc = new Scanner(System.in);
        System.out.println(sc);  //  地址值



        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        System.out.println(list);  //  [1, 2, 3, 4]
    }
}

package cn.code.Drmo007.Demo008;

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

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    /*
    直接打印对象的地址值没有意义,需要重写Object类当中的toString方法
    打印对象的属性(name,age)
     */
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", 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;
    }
}
19.2 Object类的equals方法
package cn.code.Drmo007.Demo008;
/*
    person类默认继承了Object类,所以可以使用Object类的equals方法
    boolean equals(Object obj) 指示其他那个对象是否与此对象“相等"。
    equals方法源码:
        public boolean equals(Object obj){
            return (this == obj);
        }
        参数:
            Object obj:可以传递任意的对象
            == 比较运算符,返回的是一个布尔值 true false
            基本数据类型:比较的是值
            引用数据类型:比较的是两个对象的地址值
        this是谁?哪个对象调用的方法,方法中的this就是哪个对象;p1调用的equals方法所以this就是p1
        obj是谁?传递过来的参数p2
        this == obj  --> p1 == p2
 */
public class Demo02Equals {
    public static void main(String[] args) {
        Person p1 = new Person("迪丽热巴",20);
        Person p2 = new Person("欧阳娜娜",19);
        System.out.println("p1:"+ p1);
        System.out.println("p2:" + p2);
        p1 = p2;
        boolean a = p1.equals(p2);
        System.out.println(a);  //  true

    }
}




package cn.code.Drmo007.Demo008;

import java.util.Objects;

public class Demo03Objects {
    public static void main(String[] args) {
//        String s1 = "abc";
        String s1 = null;
        String s2 = "Abc";
//        boolean a = s1.equals(s2);
//        System.out.println(a);  //  NullPointerException  null是不能调用方法的,就会抛出空指针异常
        /*
            Objects类的equals方法:对两个对象进行比较,防止空指针异常
            public static boolean equal(Object a,Object b){
                return (a == b) ||(a != null && a.equals(b));
            }
         */
        boolean b= Objects.equals(s1,s2);
        System.out.println(b);  //  false
    }
}
19.3 重写Object类的equals方法
/*
    Object类的equals方法,默认比较的是两个对象的地址值,没有意义
    所以我们要重写equals方法,比较两个对象的属性(name,age)
    问题:
        隐含着一个多态
        多态的弊端:无法使用子类特有的内容(属性和方法)
        Object  obj = p2 = new Person("迪丽热巴",19);
        解决:可以使用向下转型(强转)把obj类型转换为person
 */

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    //  getClass() != o.getClass()  使用反射技术,判断o是否是Person类型  等效于 obj instanceof person
    if (o == null || getClass() != o.getClass()) return false;
    Person person = (Person) o;
    return age == person.age &&
            Objects.equals(name, person.name);
}

@Override
public int hashCode() {
    return Objects.hash(name, 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;
}
19.4 毫秒值的概念和作用
package cn.code.Demo008;
/*
    java.util.Date:表示时间和日期的类
    类 Date  表示特定的瞬间,精确到毫秒。
    毫秒:千分之一秒  1000毫秒 = 1 秒
    特定的瞬间:一个时间点,一刹那时间

    毫秒值的作用:可以对时间和日期进行计算
    2099-01-03  到  2088-01-01  中间一共有多少天
    可以日期转换为毫秒计算,计算完毕,再把毫秒值转换为日期

    把日期转化为毫秒:
        当前的日期:2088-01-01
        时间原点(0毫秒):1970-01-01  00:00:00 (英国格林威治)
        就是计算当前日期到时间原点之间一共经历了多少毫秒

        注意:
            中国属于东八区,会把时间增加8个小时
            1970-01-01  08:00:00

        把毫秒转换为日期:
            1天 = 24 X 60 = 86400 秒 = 86400000毫秒

 */
public class Demo01Date {
    public static void main(String[] args) {
        System.out.println(System.currentTimeMillis());  //  1568899718679
    }
}
19.5 Date类的构造方法和成员方法
package cn.code.Demo008;

import java.util.Date;

public class Demo02Date {
    public static void main(String[] args) {
        demo03();
    }


    /*
        Date类的空参数构造方法
        Date()获取当前系统的日期和时间
     */
    public static void demo01(){
        Date date = new Date();
        System.out.println(date);
    }

    /*
        Date类的带参数构造方法
        Date(Long date):传递毫秒值,把毫秒值转换为Date日期
     */

    private static void demo02() {
        Date date = new Date(0L);
        System.out.println(date);  // Thu Jan 01 08:00:00 CST 1970

        date = new Date(1568899718679L);
        System.out.println(date);  //  Thu Sep 19 21:28:38 CST 2019
    }



    /*
    Long getTime() 把日期转换为毫秒值(相当于System.currentTimeMillis()方法)
      返回自 1970-01-01 00:00:00  GMT  以来此 Date 对象表示的毫秒数。
     */
    private static void demo03() {
        Date date = new Date();
        long time = date.getTime();
        System.out.println(time);  //  1568901229085
    }
}
19.6 DateFormat类的format方法和parse方法
package cn.code.Demo008;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
    java.text.DateFormat:是日期/时间格式化子类的抽象类
    作用:
        格式化(也就是日期 -> 文本)、解析(文本 -> 日期)
    成员方法:
        String format(Date date)    按照指定的模式,把Date日期,格式化为符合模式的字符串
        Date parse(String source)   把符合模式的字符串,解析为Date日期
    DateFormat类是一个抽象类,无法直接创建对象使用,可以使用DateFormat类的子类

    java.text.SimpleDateFormat extends DateFormat

    构造方法:
        SimpleDateFormat(String pattern)
        用给定的模式和默认语言环境的日期格式符号构造  SimpleDateFormat
    参数:
        String pattern:传递指定的模式
    模式:区分大小写的
        y   年
        M   月
        d   日
        H   时
        m   分
        s   秒
    写对应的模式,会把模式替换为对应的日期和时间
        “yyyy-MM-dd  HH:mm:ss”
    注意:
        模式中的字母不能更改,连接模式的符号可以改变
        “yyyy年MM月dd日    HH时mm分ss秒”
 */
public class Demo01DateFormat {
    public static void main(String[] args) throws ParseException {
        demo02();
    }
/*
    使用DateFormat类当中的方法parse,把文本解析为日期
    使用步骤:
        1. 创建SimpleDateFormat对象,构造方法中传递指定的模式
        2. 调用SimpleDateFormat对象中的方法parse,把符合构造方法中模式的字符串,解析为Date日期
        注意:
            public Date parse(String sourse) throws ParseException
            parse方法声明了一个异常叫ParseException
            如果字符串和构造方法的模式不一样,那么程序就会抛出此异常
            调用一个抛出了异常的方法,就必须的处理这个异常,要么throws继续抛出这个异常,要么try catch 自己处理
 */
    private static void demo02() throws ParseException {
//        1. 创建SimpleDateFormat对象,构造方法中传递指定的模式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日    HH时mm分ss秒");
//        2. 调用SimpleDateFormat对象中的方法parse,把符合构造方法中模式的字符串,解析为Date日期
        Date date = sdf.parse("2019年09月20日   10时30分22秒");
        System.out.println(date);
    }

    /*
        使用DateFormat类中的方法format,把日期格式化为文本
        使用步骤:
            1. 创建SimpleDateFormat对象,构造方法中传递指定的模式
            2. 调用SimpleDateFormat对象中的方法format,按照构造方法中指定的模式,把Date日期格式化为符合模式的字符串(文本)
     */
    private static void demo01() {
       // 1. 创建SimpleDateFormat对象,构造方法中传递指定的模式
        SimpleDateFormat sdf = new SimpleDateFormat();
        //  2. 调用SimpleDateFormat对象中的方法format,按照构造方法中指定的模式,把Date日期格式化为符合模式的字符串(文本)
        //   String format(Date date)    按照指定的模式,把Date日期,格式化为符合模式的字符串
        Date date = new Date();
        String d = sdf.format(date);
        System.out.println(date);
        System.out.println(d);
    }
}
练习:计算一个人已经出生了多少天
package cn.code.Demo008;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

/*
    练习:
        请使用日期时间相关的API,计算出一个人已经出生了多少天。
    分析:
        1. 使用Scanner类中的方法next,获取出生日期
        2. 使用DateFormat类中的方法parse,把字符串的出生日期,解析为Date格式的出生日期
        3. 把Date格式的出生日期,转换为毫秒值
        4. 获取当前的日期,转换为毫秒值
        5. 使用当前日期的毫秒值 - 出生日期的毫秒值
        6. 把毫秒差值转换为天(s/1000/60/60/24)
 */
public class Demo02Text {
    public static void main(String[] args) throws ParseException {
//        1. 使用Scanner类中的方法next,获取出生日期
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您的出生日期,格式:yyyy-MM-dd");
        String bir = sc.next();
//        2. 使用DateFormat类中的方法parse,把字符串的出生日期,解析为Date格式的出生日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date birs = sdf.parse(bir);
//        3. 把Date格式的出生日期,转换为毫秒值
        long birsTime = birs.getTime();
//        4. 获取当前的日期,转换为毫秒值
        long timeToday = new Date().getTime();
//        5. 使用当前日期的毫秒值 - 出生日期的毫秒值
        long time = timeToday - birsTime;
//        6. 把毫秒差值转换为天(s/1000/60/60/24)200
        System.out.println(time/1000/60/60/24);  //  7037
    }
}
19.7 Calendar类的常用成员方法
package cn.code.Demo008;

import java.util.Calendar;
import java.util.Date;

/*
    Calendar类的常用常用方法:
        public int get(int filed): 返回给定日历字段的值。
        public void set(int field,int value): 将给定的日历字段设置为给定值 。
        public abstract void add (int field,int amount): 根据日历的规则,为给定的日历字段添加或减去指定的时间量。
        public Date getTime(): 返回一个表示Calendar时间值(从历元到现在的毫秒偏移量)的Date对象。
    成员方法的参数:
        int field: 日历类的字段,可以使用Calendar类的静态成员变量获取
            public static final int YEAR = 1;   年
            public static final int MONTH = 1;   月
            public static final int DATE = 1;   月中的某一天
            public static final int DAY_OF_MONTH = 1;   月中的某一天
            public static final int HOUR = 1;   时
            public static final int MINUTE = 1;   分
            public static final int SECOND = 1;   秒

 */
public class Demo02Calendar {
    public static void main(String[] args) {
        demo04();
    }
/*
    public Date getTime(): 返回一个表示此Calendar时间值(从历元到现在的毫秒偏移量)的Date对象。
    把日历对象,转换为日期对象
 */
    private static void demo04() {
        //  使用getInstance方法获取Calendar对象
        Calendar c = Calendar.getInstance();

        Date date = c.getTime();
        System.out.println(date);
    }

    /*
        public abstract void add (int field,int amount): 根据日历的规则,为给定的日历字段添加或减去指定的时间量。
        把指定的字段增加/减少指定的值
        参数:
            int field: 传递指定的日历字段(YEAR,MONTH...)
            int amount: 增加/减少指定的值
                正数:增加
                负数:减少
     */
    private static void demo03() {
        //  使用getInstance方法获取Calendar对象
        Calendar c = Calendar.getInstance();

        //  把年增加2年
        c.add(Calendar.YEAR,2);
        //  把月份减少3个月
        c.add(Calendar.MONTH,-3);
        //  把日期增加5天
        c.add(Calendar.DATE,5);



        int year = c.get(Calendar.YEAR);
        System.out.println(year);

        int month = c.get(Calendar.MONTH);
        System.out.println(month);

        int date = c.get(Calendar.DATE);
        System.out.println(date);
    }

    /*
        public void set(int field,int value): 将给定的日历字段设置为给定值。
        参数:
            int field: 传递指定的日历字段(YEAR,MONTH...)
            int value: 给指定字段设置的值
     */
    private static void demo02() {
        //  使用getInstance方法获取Calendar对象
        Calendar c = Calendar.getInstance();

        //  设置年为2035
        c.set(Calendar.YEAR,2035);

        //  设置月为9月
        c.set(Calendar.MONTH,9);

        //  设置日为9日
        c.set(Calendar.DATE,9);

        //  同时设置年月日,可以使用set的重载方法
        c.set(2022,06,15);

        int year = c.get(Calendar.YEAR);
        System.out.println(year);

        int month = c.get(Calendar.MONTH);
        System.out.println(month);

        int date = c.get(Calendar.DATE);
        System.out.println(date);
    }

    /*
        public int get(int field): 返回给定日历字段的值。
        参数:传递指定的日历字段(YEAR,MONTH...)
        返回值:日历字段代表的具体的值
     */
    private static void demo01() {
        //  使用getInstance方法获取Calendar对象
        Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        System.out.println(year);

        int month = c.get(Calendar.MONTH);
        System.out.println(month);

        int date = c.get(Calendar.DATE);
        System.out.println(date);
    }
}
19.8 System类的常用方法
package cn.code.Demo009;

import java.util.Arrays;

/*
    java.long.System类中提供了大量的静态方法,可以获取与系统相关的信息或系统级操作,在System类的API文档中,常用方法有:
        public static long currenTimeMills(): 返回值以毫秒值为单位的当前时间。
        public static void arraycopy(Object str,int srcPos,object dest, int destPos, int lengthh): 将数组中指定的数据拷贝到另一个数组中。
 */
public class Demo01System {
    public static void main(String[] args) {
        demo02();
    }
/*
    public static void arraycopy(Object str,int srcPos,object dest, int destPos, int length): 将数组中指定的数据拷贝到另一个数组中。
    参数:
        src - 源数组
        srcPOS - 源数组中的起始位置(起始索引)
        dest - 目标数组
        destPos - 目标数据中的起始位置
        length - 要复制的数组元素的数量
   练习:
        将src数组中的前3个元素,复制到dest数组的前3个位置上
        复制元素前:
        src数组元素[1,2,3,4,5],dest数组元素[6,7,8,9,10]
        复制元素后:
        src数组元素[1,2,3,4,5],dest数组元素[1,2,3,9,10]
 */
    private static void demo02() {
        //  定义源数组
        int[] src = {1,2,3,4,5};
        //  定义目标数组
        int[] dest = {6,7,8,9,10};
        System.out.println("复制前:" + Arrays.toString(dest));  //  复制前:[6, 7, 8, 9, 10]
        //  使用System类中的arraycopy把src数组(源数组)中的前3个元素,复制到dest数组(目标数组)的前3个位置上
        System.arraycopy(src,0,dest,0,3);
        System.out.println("复制后:" + Arrays.toString(dest));  //  复制后:[1, 2, 3, 9, 10]
    }

    /*
        public static long currenTimeMills(): 返回值以毫秒值为单位的当前时间。
        用来测试程序的效率
        验证for循环打印数字1-9999所需要的时间(毫秒)
     */
    private static void demo01() {
        //  程序执行前,获取一次毫秒值
        long s = System.currentTimeMillis();
        //  执行for循环
        for (int i = 0; i < 9999; i++) {
            System.out.println(i);
        }
        //  程序执行后,获取一次毫秒值
        long e = System.currentTimeMillis();
        System.out.println("共用时:" + (e - s) + "毫秒");
    }
}
19.9 StringBuilder的原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-za2efLr4-1573821333479)(C:\Users\Think-Pad\Desktop\java\StringBuilder.jpg)]

19.10 StringBuilder的构造方法和append方法
package cn.code.Demo009;
/*
    StringBuilder的常用方法:
        piblic StringBuilder append(...): 添加任意类型数据的字符串形式,并返回当前对象自身。
 */
public class Demo02StringBuilder {
    public static void main(String[] args) {
        //  创建StringBuildrer对象
        StringBuilder bu1 = new StringBuilder();
        //  使用append方法往StringBuildrer中添加数据
        //  append方法返回值的是this
       /* StringBuilder bu2 = bu1.append("abc");
        System.out.println(bu1);  //  abc
        System.out.println(bu2);  //  abc
        System.out.println(bu1 == bu2);  //  true*/

        // 使用append方法无需接受返回值
        bu1.append("abc");
        bu1.append(true);
        bu1.append(5);
        bu1.append(8.6);
        bu1.append('中');
        System.out.println(bu1);  //  abctrue58.6中

        //  链式编程:方法返回值是一个对象,可以继续调用方法
        bu1.append("abc").append(5).append(9.4).append('中');  //  abctrue58.6中
    }
}

第二十章 包装类

20.1 包装类的概念

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3osmlyIk-1573821333480)(C:\Users\Think-Pad\Desktop\java\包装类的概念.jpg)]

20.2 装箱与拆箱
package cn.code.Demo009;

import javax.sound.midi.Soundbank;

/*
    装箱:把基本类型的数据,包装到包装类中(基本类型的数据 -> 包装类)
    构造方法:
        Integer(int value)构造一个新分配的 Integer 对象,它表示指定的 int 值。
        Integer(String s)构造一个新分配的 Integer 对象,它表示String参数所指示的int值。
            传递的字符串,必须是基本类型的字符串,否则会抛出异常“100”正确   “a”抛异常
    静态方法:
        static Integer valueOf(int i) 返回一个表示指定的int值的Integer实例。
        static Integer valueOf(String s) 返回保存指定的String 的值的Integer对象。
    拆箱:在包装类取出基本类型的数据(包装类 -> 基本类型的数据)
        成员方法:
            intValue() 以 int 类型返回该 Integer 的值

 */
public class Demo01Integer {
    public static void main(String[] args) {
        //  装箱:把基本类型的数据,包装到包装类中(基本类型的数据 -> 包装类)
        //  构造方法
        Integer int1 = new Integer(1);
        System.out.println(int1);  //  1 重写了toString方法
        //  静态方法:
        Integer int2 = Integer.valueOf(4);
        System.out.println(int2);  //  4

     //   Integer int3 = Integer.valueOf("c");
     //   System.out.println(int3);  //  NumberFormatException  数字格式化异常

        //  拆箱:在包装类中取出基本类型的数据(包装类 -> 基本类型的数据)
        int i = int1.intValue();
        System.out.println(i);  //  1


    }
}
20.3 自动装箱与自动拆箱
package cn.code.Demo009;

import java.util.ArrayList;

/*
    自动装箱与自动拆箱:基本类型的数据和包装类之间可以制动互相转换
    JDK1.5之后出现的新特性
 */
public class Demo02Integer {
    public static void main(String[] args) {
        /*
        自动装箱:直接把int类型的整数赋值包装箱
        Integer in = 1;就相当于 Integer in = new Integer(1);
         */
        Integer in = 1;
        /*
            自动装箱:in 是包装类,无法直接参与运算,可以自动转换为基本数据类型,再进行计算
            in + 2;就相当于 in.intValue() + 2 = 3
            in = in.intValue() + 2 = 3
         */
        in = in +2;
        System.out.println(in);  //  3

        ArrayList<Integer> list = new ArrayList<>();
        /*
            ArrayList集合无法直接储存整数,可以储存Integer包装类
         */
        list.add(1);   //  --> 自动装箱  list.add(new Integer(1));

        Integer a = list.get(0); //  自动拆箱  list.get(0).intValue();
        System.out.println(a);  //  1

    }
}
20.4 基本类型与字符串类型
package cn.code.Demo009;
/*
    基本类型与字符串类型之间的相互转换
    基本类型 -> 字符串(String)
        1. 基本类型的值 + "" 最简单的方法(工作中常用)
        2. 包装类的静态方法toString(参数),不是Object类的toString()重载
            static String to String(int i)返回一个表示指定整数的String对象。
        3. String类的静态方法valueOf(参数)
            static String vlueOf(int i) 返回int参数的字符串表示形式。
    字符串(String) -> 基本类型
        使用包装类的静态方法parseXXX("字符串");
            Integer类:static int pareseInt(String s)
            Double类:static double pareseDouble(String s)
 */
public class Demo03Integer {
    public static void main(String[] args) {
        //  基本类型 -> 字符串(String)
        int i1 = 100;
        String s1 = i1 + "";
        System.out.println(s1 + 200);  //  100200

        String s2 = Integer.toString(100);
        System.out.println(s2 + 200);  //  100200

        String s3 = String.valueOf(100);
        System.out.println(s3 + 200);  //  100200

        //  字符串(String)-> 基本类型
        int i = Integer.parseInt(s1);
        System.out.println(i - 10);   //  90

        int a = Integer.parseInt("a");
        System.out.println(a);  //  NumberFormatException
    }
}
20.5 Collection集合概述
  • 集合:集合是Java中提供的一种容器,可以用来存储多个数据。

    集合和数组的区别:

  • 数组的长度是固定的。集合的长度是可变的。

  • 数组中存储的是同一类型的元素,可以存储基本数据类型。集合存储的都是对象。而且对象的类型可以不一致。在开发的中一般当对象多的时候,使用集合进行存储。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PQURPLkz-1573821333482)(C:\Users\Think-Pad\Desktop\java\Collection.jpg)]

20.6 Collection集合常用功能

package cn.code.Demo009;

import java.util.ArrayList;
import java.util.Collection;

/*
    java.util.Collection接口
        所有单列集合的最顶层的接口,里边定义了所有单列集合共性的方法
        任意的单列集合都可以使用Collection接口中的方法

    共性的方法:
        public boolean add(E e): 把给定的对象添加到当前集合中。
        public void clean(): 清空集合中所有的元素。
        public boolean remove(E e): 把给定的对象在当前集合中删除。
        public boolean contains(E e): 判断当前集合中是否包含给定的对象。
        public boolean isEmpty(): 判断当前集合是否为空。
        public int size(): 返回集合中元素的个数。
        public Object[] toArray(): 把集合中的元素,存储到数组中。
 */
public class Demo01Collection {
    public static void main(String[] args) {
        //  创建集合对象,可以使用多态
        Collection<String> coll = new ArrayList<>();
        System.out.println(coll);  //  重写了toString方法  []

        /*
            public boolean add(E e): 把给定的对象添加到当前集合中。
            返回值是一个Boolean值,一般都返回true,所以可以不用接收
         */
        boolean b1 = coll.add("张三");
        System.out.println("b1 = " + b1);  //  b1 = true
        System.out.println(coll);  //  [张三]
        coll.add("田七");
        coll.add("王五");
        coll.add("赵柳");
        coll.add("李四");
        System.out.println(coll);  //  [张三, 田七, 王五, 赵柳, 李四]

        /*
            public boolean remove(E e): 把给定的对象在当前集合中删除。
            返回值是一个Boolean值,集合值存在元素,删除元素,返回true
                                 集合中不存在元素,删除失败,返回false
         */
        boolean b2 = coll.remove("李四");
        System.out.println("b2 = " + b2);
        System.out.println(coll);

        /*
            public boolean contains(E e): 判断当前集合中是否包含给定的对象。
            包含返回true
            不包含返回false
         */
        boolean b3 = coll.contains("王五");
        System.out.println(b3);

        /*
            public boolean isEmpty(): 判断当前集合是否为空。集合为空返回true,集合不为空,返回false
         */
        boolean b4 = coll.isEmpty();
        System.out.println(b4);

        /*
            public int size(): 返回集合中元素的个数。
         */
        int b5 = coll.size();
        System.out.println(b5);

        /*
        public Object[] toArray(): 把集合中的元素,存储到数组中。
         */
        Object[] arr = coll.toArray();
        for (int i = 0; i < coll.size() - 1; i++) {
            System.out.println(arr[i]);
        }

        /*
            public void clean(): 清空集合中所有的元素。
         */
        coll.clear();
        System.out.println(coll);  //  []
        System.out.println(coll.isEmpty());  //  true 
    }
}
20.7 迭代器的代码实现
package cn.code.Demo009;

import javax.sound.midi.Soundbank;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/*
    java.util.Iterator接口:迭代器(对集合进行遍历)
    有两个常用的方法
        boolean hasNext() 如果仍有元素可以迭代,则返回true
            判断集合中还有没有下一个元素,有就返回true,没有就返回false
        E next() 返回迭代的下一个元素
            取出集合的下一个元素
    Iterator迭代器是一个接口,我们无法直接使用,需要使用Iterator接口的实现类对象,获取实现类的方法比较特殊
    Collection接口中有一个方法,叫iterator(),这个方法返回的就是迭代器的实现类对象
        Iterator<E> iterator() 返回在此 collection 的元素上进行迭代的迭代器

    迭代器的使用步骤(重点):
        1. 使用集合中的方法iterator() 获取迭代器的实现类对象,使用Iterator接口接收(多态)
        2. 使用Iterator接口中的方法hasNext判断还有没有下一个元素
        3. 使用Iterator接口中的方法next取出集合中的下一个元素
 */
public class Demo01Iterator {
    public static void main(String[] args) {
        //  创建一个集合对象
        Collection<String> coll= new ArrayList<>();
        //  往集合中添加元素
        coll.add("周杰伦");
        coll.add("陈粒");
        coll.add("欧阳娜娜");
        coll.add("五月天");

        /*
            1. 使用集合中的方法iterator() 获取迭代器的实现类对象,使用Iterator接口接收(多态)
            注意:
                Iterator<E>接口也是有泛型的,迭代器的泛型跟着集合走,集合是什么泛型,迭代器就是什么泛型
         */
        //  多态  接口      实现类对象
        Iterator<String> it = coll.iterator();

        /*
            发现使用迭代器取出集合中元素代码,是一个重复的过程
            所以我们可以使用循环优化
            不知道集合中有多少元素,使用while循环
            循环结束的条件,hasNext方法返回false
         */
        while(it.hasNext()){
            System.out.println(it.next());
        }

        for (Iterator<String> it2 = coll.iterator();it2.hasNext();){
            System.out.println(it2.next());
        }


        //   2. 使用Iterator接口中的方法hasNext判断还有没有下一个元素
        boolean b = it.hasNext();
        System.out.println(b);

        //   3. 使用Iterator接口中的方法next取出集合中的下一个元素
        String next = it.next();
        System.out.println(next);
    }

}
20.8 迭代器的原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MEP7FJya-1573821333484)(C:\Users\Think-Pad\Desktop\java\迭代器的原理.jpg)]

20.9 增强for循环
package cn.code.Demo009;

import java.util.ArrayList;

/*
    增强for循环:底层使用的也是迭代器,使用for循环的格式,简化了迭代器的书写
    是JDK1.5之后出现的新特性
    Collection<E>extends Iterable<E>: 所有的单列集合都可以使用增强for
    public interface Iterable<T>实现这个接口允许对象成为“foreach”语句的目标

    增强for循环:用来遍历集合和数组

    格式:
        for(集合/数组的数据类型 变量名: 集合名/数组名)
            sout(变量名);
 */
public class Demo02Foreach {
    public static void main(String[] args) {
        demo2();
    }

    //  使用增强for循环遍历集合
    private static void demo2() {
        ArrayList<String> list = new ArrayList<>();
        list.add("杜海涛");
        list.add("何炅");
        list.add("谢娜");
        list.add("张杰");
        for (String a: list){
            System.out.println(a);
        }
    }

    //  使用增强for循环遍历数组
    private static void demo1() {
        int[] a = {1,2,3,};
        for(int b: a){
            System.out.println(b);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值