韩顺平 2021零基础学Java 学习笔记(1)(自用)

2023-11-09

第 2 章 Java 概述

2.1 Java 重要特点

  1. Java 语言是面向对象的(oop)
  2. Java 语言是健壮的。Java 的强类型机制、异常处理、垃圾的自动收集等是 Java 程序健壮性的重要保证
  3. Java 语言是跨平台性的。[即: 一个编译好的.class 文件可以在多个系统下运行,这种特性称为跨平台]
  4. Java 语言是解释型的[了解] 解释性语言:javascript,PHP, java 编译性语言: c / c++ 区别是:解释性语言,编译后的代码,不能直接被机器执行,需要解释器来执行, 编译性语言, 编译后的代码, 可 以直接被机器执行, c /c++

2.2 什么是 JDK,JRE
2.2.1 JDK 基本介绍

  1. JDK 的全称(Java Development Kit Java 开发工具包)
    JDK = JRE + java 的开发工具 [ java, javac,javadoc,javap 等]
  2. JDK 是提供给 Java 开发人员使用的,其中包含了 java 的开发工具,也包括了 JRE。所以安装了 JDK,就不用在单独 安装 JRE 了。

2.2.2 JRE 基本介绍

  1. JRE(Java Runtime Environment Java 运行环境)
    JRE = JVM + Java 的核心类库[类]
  2. 包括 Java 虚拟机(JVM Java Virtual Machine)和 Java 程序所需的核心类库等,如果想要运行一个开发好的 Java 程序, 计算机中只需要安装 JRE 即可。

2.2.3 JDK、JRE 和 JVM 的包含关系

  1. JDK = JRE + 开发工具集(例如 Javac,java 编译工具等)
  2. JRE = JVM + Java SE 标准类库(java 核心类库)
  3. 如果只想运行开发好的 .class 文件 只需要 JRE

2.3 Java 开发注意事项和细节说明
一个源文件中最多只能有一个public类。其它类的个数不限,也可以将main方法写在非public类中,然后指定运行非public类,这样入口方法就是非public的main方法

2.4 Java 转义字符
2.4.1 Java 常用的转义字符
在这里插入图片描述
2.5 注释(comment)
2.5.1 Java 中的注释类型

  1. 单行注释 //
  2. 多行注释 /* */
  3. 文档注释 /** */

2.6 DOS 命令(了解)
2.6.1 相关的知识补充: 相对路径, 绝对路径
在这里插入图片描述
2.6.2 常用的 dos 命令
在这里插入图片描述

第 3 章 变量

3.5 程序中 +号的使用
在这里插入图片描述
3.6 数据类型 每一种数据都定义了明确的数据类型,在内存中分配了不同大小的内存空间(字节)。
在这里插入图片描述
3.7 整数类型
3.7.3 整型的类型
在这里插入图片描述
3.7.4 整型的使用细节
在这里插入图片描述
3.8 浮点类型
3.8.3 浮点型的分类
在这里插入图片描述
3.8.4 说明一下

  1. 关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位
  2. 尾数部分可能丢失,造成精度损失(小数都是近似值)。

3.8.5 浮点型使用细节
在这里插入图片描述
3.9 Java API 文档
在这里插入图片描述
在这里插入图片描述
3.10 字符类型(char)
3.10.3 字符类型使用细节
在这里插入图片描述
在这里插入图片描述
3.11 ASCII 码介绍(了解)
在这里插入图片描述
3.12 Unicode 编码介绍(了解)
在这里插入图片描述
3.13 UTF-8 编码介绍(了解)
在这里插入图片描述
3.14 布尔类型:boolean
在这里插入图片描述
在这里插入图片描述
例如:
在这里插入图片描述
3.15 基本数据类型转换
3.15.1 自动类型转换
在这里插入图片描述
3.15.2 自动类型转换注意和细节
在这里插入图片描述
例如:
在这里插入图片描述
在这里插入图片描述
3.17 基本数据类型和 String 类型的转换
3.17.1 介绍和使用
在这里插入图片描述
在这里插入图片描述

第 4 章 运算符

4.1 运算符介绍
4.1.1运算符介绍
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。

  1. 算术运算符
  2. 赋值运算符
  3. 关系运算符 [比较运算符]
  4. 逻辑运算符
  5. 位运算符 [需要二进制基础]
  6. 三元运算符

4.2 算术运算符
4.2.3案例演示
在这里插入图片描述

// % 取模 ,取余 
// 在 % 的本质 看一个公式!!!! a % b = a - a / b * b 
// -10 % 3 => -10 - (-10) / 3 * 3 = -10 + 9 = -1 
// 10 % -3 = 10 - 10 / (-3) * (-3) = 10 - 9 = 1 
// -10 % -3 = (-10) - (-10) / (-3) * (-3) = -10 + 9 = -1
System.out.println(10 % 3); //1 
System.out.println(-10 % 3); // -1 
System.out.println(10 % -3); //1 
System.out.println(-10 % -3);//-1

4.2.5面试题
在这里插入图片描述

public class ArithmeticOperatorExercise01 { 
//编写一个 main 方法 
	public static void main(String[] args) {
	int i = 1;//i->1 
	i = i++; //规则使用临时变量: (1) temp = i; (2) i = i + 1; (3) i = temp; 
	System.out.println(i); // 1
	
	int j = 1; 
	j = ++j; //规则使用临时变量: (1) j = j + 1; (2) temp = j; (3) j = temp;
	System.out.println(j); //2

解析:
在这里插入图片描述
4.3 关系运算符(比较运算符)
4.3.2 关系运算符一览
在这里插入图片描述
4.3.4 细节说明

  1. 关系运算符组成的表达式,我们称为关系表达式。 例如:a > b

4.4 逻辑运算符
4.4.2 逻辑运算符一览
分为两组学习

  1. 短路与 && , 短路或 ||,取反 !
  2. 逻辑与 &,逻辑或 |,^ 逻辑异或
    在这里插入图片描述

4.4.5 && 和 & 使用区别

  1. &&短路与:如果第一个条件为 false,则第二个条件不会判断,最终结果为 false,效率高
  2. & 逻辑与:不管第一个条件是否为 false,第二个条件都要判断,效率低
  3. 开发中, 我们使用的基本是使用短路与&&, 效率高

4.4.8 || 和 | 使用区别

  1. || 短路或:如果第一个条件为 true,则第二个条件不会判断,最终结果为 true,效率高
  2. | 逻辑或:不管第一个条件是否为 true,第二个条件都要判断,效率低
  3. 开发中,我们基本使用 ||

4.4.12 练习题 1 请写出每题的输出结果
在这里插入图片描述
4.4.13 练习题 2 请写输出结果
在这里插入图片描述
4.5 赋值运算符
4.5.2 赋值运算符的分类
基本赋值运算符 = ,例如:int a = 10;
复合赋值运算符 += ,-= ,*= , /= ,%= 等

4.5.4 赋值运算符特点
在这里插入图片描述
在这里插入图片描述
4.7 运算符优先级
在这里插入图片描述
4.8.2 标识符的命名规范 [ 更加专业 ]
在这里插入图片描述
4.10 保留字
在这里插入图片描述
4.11 键盘输入语句

4.11.1 介绍
在编程中,需要接收用户输入的数据,就可以使用键盘输入语句来获取。Input.java , 需要一个 扫描器(对象), 就是 Scanner

4.11.2 步骤 :

  1. 导入该类的所在包, java.util.*
  2. 创建该类对象(声明变量)
  3. 调用里面的功能

4.11.3 案例演示:
要求:可以从控制台接收用户信息,【姓名,年龄,薪水】

import java.util.Scanner;//表示把 java.util 下的 Scanner 类导入 
public class Input { 
//编写一个 main 方法 
	public static void main(String[] args) { 
	//演示接受用户的输入 
	//步骤 
	//Scanner 类 表示 简单文本扫描器,在 java.util 包 
	//1. 引入/导入 Scanner 类所在的包 
	//2. 创建 Scanner 对象 , new 创建一个对象,体会 
	// myScanner 就是 Scanner 类的对象 
	Scanner myScanner = new Scanner(System.in); 
	//3. 接收用户输入了, 使用 相关的方法 
	System.out.println("请输入名字"); 

	//当程序执行到 next 方法时,会等待用户输入~~~ 
	String name = myScanner.next(); //接收用户输入字符串 
	System.out.println("请输入年龄"); 
	int age = myScanner.nextInt(); //接收用户输入 int 
	System.out.println("请输入薪水"); 
	double sal = myScanner.nextDouble(); //接收用户输入 double 
	System.out.println("人的信息如下:");
	System.out.println("名字=" + name + " 年龄=" + age + " 薪水=" + sal); 
	} 
}

4.12 进制
4.12.1 进制介绍
在这里插入图片描述
4.15 二进制转换成十进制示例
在这里插入图片描述
4.16 八进制转换成十进制示例
在这里插入图片描述
4.17 十六进制转换成十进制示例
规则:从最低位(右边)开始,将每个位上的数提取出来,乘以 16 的(位数-1)次方,然后求和。

4.18 十进制转换成二进制
在这里插入图片描述
4.19 十进制转换成八进制
规则:将该数不断除以 8,直到商为 0 为止,然后将每步得到的余数倒过来,就是对应的八进制。

4.20 十进制转换成十六进制
规则:将该数不断除以 16,直到商为 0 为止,然后将每步得到的余数倒过来,就是对应的十六进制。

4.21 二进制转换成八进制
规则:从低位开始,将二进制数每三位一组,转成对应的八进制数即可。
案例:请将 ob11010101 转成八进制
ob11(3)010(2)101(5) => 0325

4.22 二进制转换成十六进制
规则:从低位开始,将二进制数每四位一组,转成对应的十六进制数即可。

4.23 八进制转换成二进制
规则:将八进制数每 1 位,转成对应的一个 3 位的二进制数即可。

4.24 十六进制转换成二进制
规则:将十六进制数每 1 位,转成对应的 4 位的一个二进制数即可。

4.27 原码、反码、补码
在这里插入图片描述
例子:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
4.28 位运算符

4.28.1 java 中有 7 个位运算(&、|、^、~、>>、<<和 >>>)

4.28.2 还有 3 个位运算符 >>、<< 和 >>> , 运算规则:
在这里插入图片描述
4.28.3 应用案例
在这里插入图片描述
4.29 本章作业
在这里插入图片描述
在这里插入图片描述

第 5 章 程序控制结构

5.1 程序流程控制介绍
在这里插入图片描述
5.2 顺序控制
在这里插入图片描述
5.3 分支控制 if-else
5.3.1 分支控制 if-else 介绍
在这里插入图片描述
5.3.2单分支
在这里插入图片描述
5.4.1 双分支
在这里插入图片描述
5.4.4 多分支

多分支的流程图
在这里插入图片描述
案例演示 2
在这里插入图片描述
5.6 switch 分支结构
5.6.1 基本语法
在这里插入图片描述
5.6.2 switch 分支结构流程图
在这里插入图片描述

5.6.4 switch 注意事项和细节讨论
在这里插入图片描述
5.6.5 switch 课堂练习

  1. 对学生成绩大于 60 分的,输出"合格"。低于 60 分的,输出"不合格"。(注:输入的成绩不能大于 100), 提示 成绩/60
//思路分析 
//1. 这道题,可以使用 分支来完成, 但是要求使用 switch 
//2. 这里我们需要进行一个转换, 编程思路 : 
// 如果成绩在 [60,100] , (int)(成绩/60) = 1 
// 如果成绩在 [0,60) , (int)(成绩/60) = 0 

//代码实现 
double score = 1.1; 
//使用 if-else 保证输入的成绩有有效的 0-100 
if( score >= 0 && score <= 100) { 
	switch ((int)(score / 60)) { 
		case 0 : 
			System.out.println("不合格"); 
			break; 
		case 1 : 
			System.out.println("合格"); 
			break; 
	} 
} else { 
	System.out.println("输入的成绩在 0-100"); 
}
  1. 根据用于指定月份,打印该月份所属的季节。3,4,5 春季 6,7,8 夏季 9,10,11 秋季 12, 1, 2 冬季 [ 课堂练习, 提示 使用穿透 ]
//思路分析 
//1. 创建 Scanner 对象, 接收用户输入 
//2. 使用 int month 接收 
//3. 使用 switch 来匹配 ,使用穿透来完成,比较简洁 

Scanner myScanner = new Scanner(System.in); 
System.out.println("输入月份"); 
int month = myScanner.nextInt(); 
switch(month) { 
	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; 
	case 1: 
	case 2: 
	case 12: 
		System.out.println("这是冬季"); 
		break; 
	default : 
		System.out.println("你输入的月份不对(1-12)"); 
}

5.6.6 switch 和 if 的比较
在这里插入图片描述
5.7 for 循环控制

5.7.3 for 循环流程图
在这里插入图片描述

5.7.5 for 循环练习题

  1. 打印 1~100 之间所有是 9 的倍数的整数,统计个数 及 总和.[化繁为简,先死后活]
public class ForExercise { 
	//编写一个 main 方法 
	public static void main(String[] args) { 
		//打印 1~100 之间所有是 9 的倍数的整数,统计个数 及 总和.[化繁为简,先死后活] 
		//老韩的两个编程思想(技巧) 
		//1. 化繁为简 : 即将复杂的需求,拆解成简单的需求,逐步完成 编程 = 思想 --练习-> 代码 
		//2. 先死后活 : 先考虑固定的值,然后转成可以灵活变化的值 
		
		//思路分析 
		//打印 1~100 之间所有是 9 的倍数的整数,统计个数及总和 
		//化繁为简
		//(1) 完成 输出 1-100 的值 
		//(2) 在输出的过程中,进行过滤,只输出 9 的倍数 i % 9 ==0 
		//(3) 统计个数 定义一个变量 int count = 0; 当 条件满足时 count++; 
		//(4) 总和 , 定义一个变量 int sum = 0; 当条件满足时累积 sum += i; 
		//先死后活 
		//(1) 为了适应更好的需求,把范围的开始的值和结束的值,做出变量 
		//(2) 还可以更进一步 9 倍数也做成变量 int t = 9; 
	
		int count = 0; //统计 9 的倍数个数 变量 
		int sum = 0; //总和 
		int start = 10; 
		int end = 200; 
		int t = 5; //倍数 
		for(int i = start; i <= end; i++) { 
			if( i % t == 0) { 
				System.out.println("i=" + i); 
				count++; 
				sum += i;//累积 
			} 
		}

		System.out.println("count=" + count); 
		System.out.println("sum=" + sum); 
	} 
}

5.8 while 循环控制

5.8.2 while 循环执行流程分析

  1. 画出流程图
    在这里插入图片描述
    5.9 do…while 循环控制

5.9.3 do…while 循环执行流程图
在这里插入图片描述
5.10.4 经典的打印金字塔
在这里插入图片描述

public class Stars { 
	//编写一个 main 方法 
	public static void main(String[] args) { 
		/* 
			  * 
			*  * 
		   *    * 
		  ******** 
	
		思路分析 
		化繁为简 
		1. 先打印一个矩形 
		***** 
		*****
		***** 
		***** 
		*****
		
		2. 打印半个金字塔
		* 		//第 1 层 有 1 个* 
		** 		//第 2 层 有 2 个* 
		*** 	//第 3 层 有 3 个* 
		**** 	//第 4 层 有 4 个* 
		***** 	//第 5 层 有 5 个*
		
		3. 打印整个金字塔
		    * 		//第 1 层 有 1 个* 2 * 1 -1 有 4=(总层数-1)个空格 
		   *** 		//第 2 层 有 3 个* 2 * 2 -1 有 3=(总层数-2)个空格 
		  ***** 	//第 3 层 有 5 个* 2 * 3 -1 有 2=(总层数-3)个空格 
		 ******* 	//第 4 层 有 7 个* 2 * 4 -1 有 1=(总层数-4)个空格 
		********* 	//第 5 层 有 9 个* 2 * 5 -1 有 0=(总层数-5)个空格
		
		4. 打印空心的金字塔 [最难的]
		    * 		//第 1 层 有 1 个* 当前行的第一个位置是*,最后一个位置也是* 
		   * * 		//第 2 层 有 2 个* 当前行的第一个位置是*,最后一个位置也是* 
		  *   * 	//第 3 层 有 2 个* 当前行的第一个位置是*,最后一个位置也是* 
		 *     * 	//第 4 层 有 2 个* 当前行的第一个位置是*,最后一个位置也是* 
		********* 	//第 5 层 有 9 个* 全部输出*
		
		先死后活
		5 层数做成变量 int totalLevel = 5;
		*/
		int totalLevel = 20; //层数 
		for(int i = 1; i <= totalLevel; i++) { //i 表示层数 
			//在输出*之前,还有输出 对应空格 = 总层数-当前层 
			for(int k = 1; k <= totalLevel - i; k++ ) { 
				System.out.print(" "); 
			}
			//控制打印每层的*个数 
			for(int j = 1;j <= 2 * i - 1;j++) { 
				//当前行的第一个位置是*,最后一个位置也是*, 最后一层全部 * 
				if(j == 1 || j == 2 * i - 1 || i == totalLevel) { 
					System.out.print("*"); 
				} else { //其他情况输出空格 
					System.out.print(" "); 
				} 
			}
			//每打印完一层的*后,就换行 println 本身会换行 
			System.out.println(""); 
		} 
	} 
}

5.11 跳转控制语句-break

5.11.1 看下面一个需求
在这里插入图片描述
在这里插入图片描述
5.11.6 注意事项和细节说明:
在这里插入图片描述
5.12 跳转控制语句-continue

5.12.1 基本介绍:
在这里插入图片描述
5.13 跳转控制语句-return
return 使用在方法,表示跳出所在的方法,在讲解方法的时候,会详细的介绍,这里我们简单的提一下。注意:如果 return 写在 main 方法,则退出程序。

第 6 章 数组、排序和查找

6.1 为什么需要数组

6.1.1 数组介绍
在这里插入图片描述
6.1.2 数组快速入门
可以通过 数组名.length 得到数组的大小/长度

6.2 数组的使用
在这里插入图片描述
注意:int a[ ] = new int [5] 和 int[ ] a = new int [5] 是等价的。

6.2.1 使用方式 2-动态初始化
在这里插入图片描述
6.2.2 使用方式 3-静态初始化
在这里插入图片描述
6.3 数组使用注意事项和细节
在这里插入图片描述
6.5 数组赋值机制
在这里插入图片描述
6.6 数组拷贝
在这里插入图片描述
在这里插入图片描述
6.7 数组反转
在这里插入图片描述
方式 1:通过找规律反转

public class ArrayReverse { 
	//编写一个 main 方法 
	public static void main(String[] args) { 
		//定义数组 
		int[] arr = {11, 22, 33, 44, 55, 66}; 
		//规律 
		//1. 把 arr[0] 和 arr[5] 进行交换 {66,22,33,44,55,11}
		//2. 把 arr[1] 和 arr[4] 进行交换 {66,55,33,44,22,11} 
		//3. 把 arr[2] 和 arr[3] 进行交换 {66,55,44,33,22,11} 
		//4. 一共要交换 3 次 = arr.length / 2 
		//5. 每次交换时,对应的下标 是 arr[i] 和 arr[arr.length - 1 -i] 
		//代码 
		//优化 
		int temp = 0; 
		int len = arr.length; //计算数组的长度 
		for( int i = 0; i < len / 2; i++) { 
			temp = arr[len - 1 - i];//保存 
			arr[len - 1 - i] = arr[i]; 
			arr[i] = temp; 
		}

		System.out.println("===翻转后数组==="); 
		for(int i = 0; i < arr.length; i++) { 
			System.out.print(arr[i] + "\t");//66,55,44,33,22,11 
		} 
	} 
}

方式 2:使用逆序赋值方式

public class ArrayReverse02 { 
	//编写一个 main 方法 
	public static void main(String[] args) { 
		//定义数组 
		int[] arr = {11, 22, 33, 44, 55, 66}; 
		//使用逆序赋值方式 
		//1. 先创建一个新的数组 arr2 ,大小 arr.length 
		//2. 逆序遍历 arr ,将 每个元素拷贝到 arr2 的元素中(顺序拷贝) 
		//3. 建议增加一个循环变量 j -> 0 -> 5 
		int[] arr2 = new int[arr.length]; 
		//逆序遍历 arr 
		for(int i = arr.length - 1, j = 0; i >= 0; i--, j++) { 
			arr2[j] = arr[i]; 
		}
		//4. 当 for 循环结束,arr2 就是一个逆序的数组 {66, 55, 44,33, 22, 11} 
		//5. 让 arr 指向 arr2 数据空间, 此时 arr 原来的数据空间就没有变量引用 
		// 会被当做垃圾,销毁 
		arr = arr2; 
		System.out.println("====arr 的元素情况====="); 
		//6. 输出 arr 看看 
		for(int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + "\t"); 
		} 
	} 
}

6.9 排序的介绍
在这里插入图片描述
6.10 冒泡排序法
冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从后向前(从下标较大的元素开始),依次比较相邻元素 的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。
在这里插入图片描述
在这里插入图片描述

public class BubbleSort { 
	//编写一个 main 方法 
	public static void main(String[] args) {
	int[] arr = {24, 69, 80, 57, 13, -1, 30, 200, -110}; 
	int temp = 0; //用于辅助交换的变量 
	
	//将多轮排序使用外层循环包括起来即可 
	for( int i = 0; i < arr.length - 1; i++) {//外层循环是 4 次 
		for( int j = 0; j < arr.length - 1 - i; j++) {//4 次比较-3 次-2 次-1 次 
			//如果前面的数>后面的数,就交换 
			if(arr[j] > arr[j + 1]) { 
				temp = arr[j]; 
				arr[j] = arr[j+1]; 
				arr[j+1] = temp; 
			} 
		}
		System.out.println("\n==第"+(i+1)+"轮=="); 
		for(int j = 0; j < arr.length; j++) { 
			System.out.print(arr[j] + "\t");
		} 
	}
}

6.12 查找

6.12.1 介绍:
在 java 中,我们常用的查找有两种:

  1. 顺序查找
  2. 二分查找

6.12.2 案例演示:
有一个数列:白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王猜数游戏:从键盘中任意输入一个名称,判断数列中是否 包含此名称【顺序查找】 要求: 如果找到了,就提示找到,并给出下标值。

import java.util.Scanner; 
public class SeqSearch { 
	//编写一个 main 方法 
	public static void main(String[] args) { 
		/*
		思路分析 
		1. 定义一个字符串数组 
		2. 接收用户输入, 遍历数组,逐一比较,如果有,则提示信息,并退出 
		*/
		//定义一个字符串数组 
		String[] names = {"白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王"}; 
		Scanner myScanner = new Scanner(System.in); 
		System.out.println("请输入名字"); 
		String findName = myScanner.next(); 
		
		//遍历数组,逐一比较,如果有,则提示信息,并退出 
		//这里老师给大家一个编程思想/技巧, 一个经典的方法 
		int index = -1; 
		for(int i = 0; i < names.length; i++) { 
			//比较 字符串比较 equals, 如果要找到名字就是当前元素 
			if(findName.equals(names[i])) { 
				System.out.println("恭喜你找到 " + findName); 
				System.out.println("下标为= " + i); 
				//把 i 保存到 index 
				index = i; 
				break;//退出 
			} 
		}
		if(index == -1) { //没有找到 
			System.out.println("sorry ,没有找到 " + findName); 
		}
	}
}

6.14 二维数组的使用

6.14.2 使用方式 1: 动态初始化
在这里插入图片描述
在这里插入图片描述
6.14.3 使用方式 2: 动态初始化
在这里插入图片描述
6.14.4 使用方式 3: 动态初始化-列数不确定
在这里插入图片描述

public class TwoDimensionalArray03 {
	//编写一个 main 方法 
	public static void main(String[] args) { 
		//创建 二维数组,一个有 3 个一维数组,但是每个一维数组还没有开数据空间 
		int[][] arr = new int[3][]; 
		for(int i = 0; i < arr.length; i++) {//遍历 arr 每个一维数组 
			//给每个一维数组开空间 new 
			//如果没有给一维数组 new ,那么arr[i]就是 null 
			arr[i] = new int[i + 1]; 
			
			//遍历一维数组,并给一维数组的每个元素赋值 
			for(int j = 0; j < arr[i].length; j++) { 
				arr[i][j] = i + 1;//赋值 
			}
		}
		System.out.println("=====arr 元素====="); 
		//遍历 arr 输出 
		for(int i = 0; i < arr.length; i++) { 
			//输出 arr 的每个一维数组 
			for(int j = 0; j < arr[i].length; j++) { 
				System.out.print(arr[i][j] + " "); 
			}
			System.out.println();//换行 
		} 
	} 
}

6.14.5 使用方式 4: 静态初始化
在这里插入图片描述
6.15 二维数组的应用案例
使用二维数组打印一个 10 行杨辉三角
在这里插入图片描述

public class YangHui { 
	//编写一个 main 方法 
	public static void main(String[] args) {
		/*
			规律
			1.第一行有 1 个元素, 第 n 行有 n 个元素 
			2. 每一行的第一个元素和最后一个元素都是 1 
			3. 从第三行开始, 对于非第一个元素和最后一个元素的元素的值. arr[i][j] 
			arr[i][j] = arr[i-1][j] + arr[i-1][j-1]; //必须找到这个规律 
		*/ 
		int[][] yangHui = new int[12][]; 
		for(int i = 0; i < yangHui.length; i++) {//遍历 yangHui 的每个元素 
			//给每个一维数组(行) 开空间 
			yangHui[i] = new int[i+1]; 
			//给每个一维数组(行) 赋值 
			for(int j = 0; j < yangHui[i].length; j++){ 
				//每一行的第一个元素和最后一个元素都是 1 
				if(j == 0 || j == yangHui[i].length - 1) { 
					yangHui[i][j] = 1; 
				} else {//中间的元素 
					yangHui[i][j] = yangHui[i-1][j] + yangHui[i-1][j-1]; 
				}
			} 
		}
		//输出杨辉三角 
		for(int i = 0; i < yangHui.length; i++) { 
			for(int j = 0; j < yangHui[i].length; j++) {//遍历输出该行 
				System.out.print(yangHui[i][j] + "\t"); 
			}
			System.out.println();//换行. 
		} 
	} 
}

6.16 二维数组使用细节和注意事项
在这里插入图片描述
6.17 二维数组课堂练习
在这里插入图片描述

第 7 章 面向对象编程(基础部分)

7.1 类与对象

7.1.5 类与对象的关系示意图
在这里插入图片描述
7.1.6 类与对象的关系示意图
在这里插入图片描述
7.1.8 类和对象的区别和联系
在这里插入图片描述
7.1.9 对象在内存中存在形式(重要,必须搞清楚)
在这里插入图片描述
7.1.10 属性/成员变量/字段
在这里插入图片描述
注意事项和细节说明:
在这里插入图片描述
7.1.13 类和对象的内存分配机制
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
看一个练习题,并分析画出内存布局图,进行分析
在这里插入图片描述
最后一句会报 NullPointerException 异常。

7.2 成员方法

7.2.3 方法的调用机制原理:(重要!-示意图!!!)
在这里插入图片描述
7.2.5 成员方法的好处
在这里插入图片描述
7.2.7 注意事项和使用细节
在这里插入图片描述
在这里插入图片描述

public class MethodDetail02 { 
	//编写一个 main 方法 
	public static void main(String[] args) { 
		A a = new A(); 
		//a.sayOk(); 
		a.m1(); 
	} 
}
class A { 
	//同一个类中的方法调用:直接调用即可 
	public void print(int n) { 
		System.out.println("print()方法被调用 n=" + n);
	}
	public void sayOk() { //sayOk 调用 print(直接调用即可) 
		print(10); 
		System.out.println("继续执行 sayOK()~~~"); 
	}
	//跨类中的方法 A 类调用 B 类方法:需要通过对象名调用 
	public void m1() { 
		//创建 B 对象, 然后在调用方法即可 
		System.out.println("m1() 方法被调用"); 
		B b = new B(); 
		b.hi(); 
		System.out.println("m1() 继续执行:)"); 
	} 
}
class B { 
	public void hi() { 
		System.out.println("B 类中的 hi()被执行"); 
	} 
}

7.3 成员方法传参机制(非常非常重要)
在这里插入图片描述

public class MethodParameter01 { 
	//编写一个 main 方法 
	public static void main(String[] args) { 
		int a = 10; 
		int b = 20; //创建 AA 对象 名字 obj 
		AA obj = new AA(); 
		obj.swap(a, b); //调用 swap 
		System.out.println("main 方法 a=" + a + " b=" + b);//a=10 b=20 
	} 
}
class AA { 
	public void swap(int a,int b){ 
		System.out.println("\na 和 b 交换前的值\na=" + a + "\tb=" + b);//a=10 b=20 
		//完成了 a 和 b 的交换 
		int tmp = a; 
		a = b; 
		b = tmp; 
		System.out.println("\na 和 b 交换后的值\na=" + a + "\tb=" + b);//a=20 b=10 
	} 
}

在这里插入图片描述
7.3.2 引用数据类型的传参机制
在这里插入图片描述
在看一个案例,下面的方法会对原来的对象有影响吗?
p=null 和 p = new Person(); 对应示意图
在这里插入图片描述
7.4 方法递归调用(非常非常重要,比较难)

7.4.4 递归重要规则
在这里插入图片描述
7.4.5 课堂练习
在这里插入图片描述

public class RecursionExercise01 { 
	//编写一个 main 方法 
	public static void main(String[] args) { 
		T t1 = new T(); 
		int n = 7; 
		int res = t1.fibonacci(n); 
		if(res != -1) { 
			System.out.println("当 n="+ n +" 对应的斐波那契数=" + res); 
		} 
		//桃子问题 
		int day = 0; 
		int peachNum = t1.peach(day); 
		if(peachNum != -1) { 
			System.out.println("第 " + day + "天有" + peachNum + "个桃子"); 
		}
	} 
}
class T {
	/*
	请使用递归的方式求出斐波那契数 1,1,2,3,5,8,13...给你一个整数 n,求出它的值是多 
	思路分析 
	1. 当 n = 1 斐波那契数 是 1 
	2. 当 n = 2 斐波那契数 是 1
	3. 当 n >= 3 斐波那契数 是前两个数的和 
	4. 这里就是一个递归的思路 
	*/ 
	public int fibonacci(int n) { 
		if( n >= 1) { 
			if( n == 1 || n == 2) { 
				return 1; 
			} else { 
				return fibonacci(n-1) + fibonacci(n-2); 
			} 
		} else { 
			System.out.println("要求输入的 n>=1 的整数"); 
			return -1; 
		} 
	}
	/*
	猴子吃桃子问题:有一堆桃子,猴子第一天吃了其中的一半,并再多吃了一个! 
	以后每天猴子都吃其中的一半,然后再多吃一个。当到第 10 天时, 
	想再吃时(即还没吃),发现只有 1 个桃子了。问题:最初共多少个桃子? 
	思路分析 逆推 
	1. day = 10 时 有 1 个桃子 
	2. day = 9 时 有 (day10 + 1) * 2 = 4 
	3. day = 8 时 有 (day9 + 1) * 2 = 10 
	4. 规律就是 前一天的桃子 = (后一天的桃子 + 1) *2
	5. 递归 
	 */ 
	 public int peach(int day) { 
	 	if(day == 10) {//第 10 天,只有 1 个桃 
	 		return 1; 
	 	} else if ( day >= 1 && day <=9 ) { 
	 		return (peach(day + 1) + 1) * 2;//规则,自己要想 
	 	} else { 
	 		System.out.println("day 在 1-10"); return -1; 
	 	} 
	 } 
}

7.4.6 递归调用应用实例-迷宫问题
在这里插入图片描述

public class MiGong { 
	//编写一个 main 方法 
	public static void main(String[] args) { 
		//思路 
		//1. 先创建迷宫,用二维数组表示 int[][] map = new int[8][7]; 
		//2. 先规定 map 数组的元素值: 0 表示可以走 1 表示障碍物 
		int[][] map = new int[8][7]; 
		//3. 将最上面的一行和最下面的一行,全部设置为 1 
		for(int i = 0; i < 7; i++) { 
			map[0][i] = 1; 
			map[7][i] = 1; 
		}
		//4.将最右面的一列和最左面的一列,全部设置为 1 
		for(int i = 0; i < 8; i++) {
			map[i][0] = 1; 
			map[i][6] = 1; 
		}
		map[3][1] = 1; 
		map[3][2] = 1; 
		map[2][2] = 1; //测试回溯 

		//输出当前的地图 
		System.out.println("=====当前地图情况======"); 
		for(int i = 0; i < map.length; i++) { 
			for(int j = 0; j < map[i].length; j++) { 
				System.out.print(map[i][j] + " ");//输出一行 
			}
			System.out.println(); 
		}
		//使用 findWay 给老鼠找路 
		T t1 = new T(); 
		//下右上左 
		t1.findWay(map, 1, 1); 
		System.out.println("\n====找路的情况如下=====");
		for(int i = 0; i < map.length; i++) { 
			for(int j = 0; j < map[i].length; j++) { 
				System.out.print(map[i][j] + " ");//输出一行 
			}
			System.out.println(); 
		} 
	} 
}
class T { 
	//使用递归回溯的思想来解决老鼠出迷宫 
	//老韩解读 
	//1. findWay 方法就是专门来找出迷宫的路径 
	//2. 如果找到,就返回 true ,否则返回 false 
	//3. map 就是二维数组,即表示迷宫 
	//4. i,j 就是老鼠的位置,初始化的位置为(1,1) 
	//5. 因为我们是递归的找路,所以我先规定 map 数组的各个值的含义 
	// 0 表示可以走 1 表示障碍物 2 表示可以走 3 表示走过,但是走不通是死路 
	//6. 当 map[6][5] =2 就说明找到通路,就可以结束,否则就继续找. 
	//7. 先确定老鼠找路策略 下->右->上->左
	public boolean findWay(int[][] map , int i, int j) { 
		if(map[6][5] == 2) {//说明已经找到 
			return true; 
		} else { 
			if(map[i][j] == 0) {//当前这个位置 0,说明表示可以走 
				//我们假定可以走通 
				map[i][j] = 2; 
				//使用找路策略,来确定该位置是否真的可以走通 
				//下->右->上->左 
				if(findWay(map, i + 1, j)) {//先走下 
					return true; 
				} else if(findWay(map, i, j + 1)){//右 
					return true; 
				} else if(findWay(map, i-1, j)) {//上 
					return true; 
				} else if(findWay(map, i, j-1)){//左 
					return true; 
				} else { 
					map[i][j] = 3; 
					return false; 
				} 
			} else { //map[i][j] = 1 , 2, 3 
				return false; 
			} 
		}
	}
}

在这里插入图片描述
在这里插入图片描述
7.4.7 递归调用应用实例-汉诺塔
在这里插入图片描述
在这里插入图片描述
HanoiTower.java

public class HanoiTower { 
	//编写一个 main 方法 
	public static void main(String[] args) { 
		Tower tower = new Tower(); 
		tower.move(64, 'A', 'B', 'C'); 
	} 
}
class Tower { 
	//方法 
	//num 表示要移动的个数, a, b, c 分别表示 A 塔,B 塔, C 塔 
	public void move(int num , char a, char b ,char c) { 
		//如果只有一个盘 num = 1
		if(num == 1) { 
			System.out.println(a + "->" + c); 
		} else { 
			//如果有多个盘,可以看成两个 , 最下面的和上面的所有盘(num-1) 
			//(1)先移动上面所有的盘到 b, 借助 c 
			move(num - 1 , a, c, b); 
			//(2)把最下面的这个盘,移动到 c 
			System.out.println(a + "->" + c); 
			//(3)再把 b 塔的所有盘,移动到 c ,借助 a 
			move(num - 1, b, a, c); 
		} 
	} 
}

7.4.8 递归调用应用实例-八皇后问题[同学们先尝试做,后面老师评讲.]
在这里插入图片描述
在这里插入图片描述
7.5 方法重载(OverLoad)

7.5.1 基本介绍
java 中允许同一个类中,多个同名方法的存在,但要求 形参列表不一致!
比如:System.out.println(); 其中 out 是 PrintStream 类型

7.5.2 重载的好处

  1. 减轻了起名的麻烦
  2. 减轻了记名的麻烦

7.5.4 注意事项和使用细节
在这里插入图片描述
7.6 可变参数

7.6.1 基本概念
java 允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。
就可以通过可变参数实现

7.6.2 基本语法
访问修饰符 返回类型 方法名(数据类型… 形参名) { }

7.6.3 快速入门案例(VarParameter01.java)
看一个案例:类 HspMethod,方法 sum 【可以计算 2 个数的和,3 个数的和 , 4、5, 。。】

public class VarParameter01 { 
	//编写一个 main 方法 
	public static void main(String[] args) { 
		HspMethod m = new HspMethod(); 
		System.out.println(m.sum(1, 5, 100)); //106 
		System.out.println(m.sum(1,19)); //20 
	} 
}
class HspMethod { 
	//可以计算 2 个数的和,3 个数的和 , 4. 5, 。。
	//老韩解读
	//1. int... 表示接受的是可变参数,类型是 int ,即可以接收多个 int(0-多) 
	//2. 使用可变参数时,可以当做数组来使用 即 nums 可以当做数组 
	//3. 遍历 nums 求和即可 
	public int sum(int... nums) { 
		//System.out.println("接收的参数个数=" + nums.length); 
		int res = 0; 
		for(int i = 0; i < nums.length; i++) { 
			res += nums[i]; 
		}
		return res; 
	} 
}

7.6.4 注意事项和使用细节
在这里插入图片描述

public class VarParameterDetail { 
	//编写一个 main 方法 
	public static void main(String[] args) {
		//细节: 可变参数的实参可以为数组 
		int[] arr = {1, 2, 3}; 
		T t1 = new T(); 
		t1.f1(arr); 
	} 
}
class T { 
	public void f1(int... nums) { 
		System.out.println("长度=" + nums.length); 
	}
	//细节: 可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后 
	public void f2(String str, double... nums) { 
	}
	//细节: 一个形参列表中只能出现一个可变参数 
	//下面的写法是错的. 
	// public void f3(int... nums1, double... nums2) { 
	// } 
}

7.7 作用域

7.7.1 基本使用
在这里插入图片描述
7.7.2 注意事项和细节使用
在这里插入图片描述
7.8 构造方法/构造器

7.8.2 基本语法
在这里插入图片描述
7.8.3 基本介绍
在这里插入图片描述
7.8.5 注意事项和使用细节
在这里插入图片描述
7.9 对象创建的流程分析

7.9.1 看一个案例
在这里插入图片描述
在这里插入图片描述
7.10 this 关键字

7.10.2 深入理解 this
在这里插入图片描述
7.10.3 this 的注意事项和使用细节
在这里插入图片描述
7.11 本章作业
在这里插入图片描述

public class Homework01 { 
	//编写一个main方法
	public static void main(String[] args) {
		A01 a01 = new A01();
		double[] arr = {1, 1.4, -1.3, 89.8, 123.8 , 66}; //;{};
		Double res = a01.max(arr);
		if(res != null) {
			System.out.println("arr的最大值=" + res);
		} else {
			System.out.println("arr的输入有误, 数组不能为null, 或者{}");
		}
	}
}
/*
编写类A01,定义方法max,实现求某个double数组的最大值,并返回

思路分析
1. 类名 A01
2. 方法名 max
3. 形参 (double[])
4. 返回值 double

先完成正常业务,然后再考虑代码健壮性
 */
class A01 {
	public Double max(double[] arr) {
		//老韩先判断arr是否为null,然后再判断 length 是否>0
		if( arr!= null && arr.length > 0 ) {
			//保证arr至少有一个元素 
			double max = arr[0];//假定第一个元素就是最大值
			for(int i = 1; i < arr.length; i++) {
				if(max < arr[i]) {
					max = arr[i];
				}
			}
			return max;//double
		} else {
			return null;
		}
	}
}

在这里插入图片描述

public class Homework06 { 
	//编写一个main方法
	public static void main(String[] args) {
		Cale cale = new Cale(2, 10);
		System.out.println("和=" + cale.sum());
		System.out.println("差=" + cale.minus());
		System.out.println("乘=" + cale.mul());
		Double divRes = cale.div();
		if(divRes != null) {
			System.out.println("除=" + divRes);
		} 
	}
}
/*
 编程创建一个Cale计算类,在其中定义2个变量表示两个操作数,
 定义四个方法实现求和、差、乘、商(要求除数为0的话,要提示) 并创建两个对象,分别测试 
 */
class Cale {
	double num1;
	double num2;
	public Cale(double num1, double num2) {
		this.num1 = num1;
		this.num2 = num2;
	}
	//和
	public double sum() {
		return num1 + num2;
	}
	//差
	public double minus() {
		return num1 - num2;
	}
	//乘积
	public double mul() {
		return num1 * num2;
	}
	//除法
	public Double div() {
		//判断
		if(num2 == 0) {
			System.out.println("num2 不能为0");
			return null;
		} else {
			return num1 / num2;
		}
	}
}

第 8 章 面向对象编程(中级部分)

8.3.4 课堂练习
在这里插入图片描述
8.3.5 IDEA 常用快捷键
在这里插入图片描述
第11点也可以用 alt + enter

8.3.6 模板/自定义模板
在这里插入图片描述
8.4 包

8.4.2 包的三大作用
在这里插入图片描述
8.4.3 包基本语法
在这里插入图片描述
8.4.4 包的本质分析(原理)
在这里插入图片描述
8.4.5 快速入门
在这里插入图片描述
8.4.6 包的命名
在这里插入图片描述
8.4.7 常用的包
在这里插入图片描述
8.4.8 如何引入包
在这里插入图片描述

package com.hspedu.pkg; 
import java.util.Arrays; 
//注意: 
//老韩建议:我们需要使用到哪个类,就导入哪个类即可,不建议使用 *导入 
//import java.util.Scanner; //表示只会引入 java.util 包下的 Scanner 
//import java.util.*;//表示将 java.util 包下的所有类都引入(导入) 
public class Import01 { 
	public static void main(String[] args) { 
		//使用系统提供 Arrays 完成 数组排序 
		int[] arr = {-1, 20, 2, 13, 3}; 
		//比如对其进行排序 
		//传统方法是,自己编写排序(冒泡) 
		//系统是提供了相关的类,可以方便完成 
		Arrays.sort(arr); 
		//输出排序结果 
		for (int i = 0; i < arr.length ; i++) { 
			System.out.print(arr[i] + "\t"); 
		}
	}
}

8.4.9 注意事项和使用细节
在这里插入图片描述
8.5 访问修饰符

8.5.1 基本介绍
在这里插入图片描述
8.5.2 种访问修饰符的访问范围
在这里插入图片描述
8.5.3 使用的注意事项
在这里插入图片描述
8.6 面向对象编程三大特征

8.6.1 基本介绍
面向对象编程有三大特征:封装、继承和多态。

8.6.2 封装介绍
在这里插入图片描述
8.6.3 封装的理解和好处
在这里插入图片描述
8.6.4 封装的实现步骤 (三步)
在这里插入图片描述
8.7.1 将构造器和 setXxx 结合
看一个案例

//有三个属性的构造器 
public Person(String name, int age, double salary) { 
	// this.name = name; 
	// this.age = age; 
	// this.salary = salary; 
	//我们可以将 set 方法写在构造器中,这样仍然可以验证 
	setName(name); 
	setAge(age); 
	setSalary(salary); 
}

8.8 面向对象编程-继承

8.8.2 继承基本介绍和示意图
在这里插入图片描述
8.8.3 继承的基本语法
在这里插入图片描述
8.8.5 继承给编程带来的便利

  1. 代码的复用性提高了
  2. 代码的扩展性和维护性提高了

8.8.6 继承的深入讨论/细节问题
在这里插入图片描述
在这里插入图片描述
8.8.7 继承的本质分析(重要)
在这里插入图片描述

package com.hspedu.extend_; 
/**
 * 讲解继承的本质 
 */ 
public class ExtendsTheory { 
	public static void main(String[] args) { 
		Son son = new Son();//内存的布局 
		//?-> 这时请大家注意,要按照查找关系来返回信息 
		//(1) 首先看子类是否有该属性 
		//(2) 如果子类有这个属性,并且可以访问,则返回信息 
		//(3) 如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息..) 
		//(4) 如果父类没有就按照(3)的规则,继续找上级父类,直到 Object...
		System.out.println(son.name);//返回就是大头儿子 
		//System.out.println(son.age);//返回的就是 39 
		//System.out.println(son.getAge());//返回的就是 39 
		System.out.println(son.hobby);//返回的就是旅游 
	} 
}
class GrandPa { //爷类 
	String name = "大头爷爷";
	String hobby = "旅游"; 
}
class Father extends GrandPa {//父类 
	String name = "大头爸爸"; 
	private int age = 39; 
	public int getAge() { 
		return age; 
	} 
}
class Son extends Father { //子类 
	String name = "大头儿子"; 
}

子类创建的内存布局:
在这里插入图片描述
如果Father里的age是private,即使GrandPa里也有age,是public,访问age的时候一样到Father就会停止,不会继续查看GrandPa里是否有age。

8.8.8 课堂练习
在这里插入图片描述
由于B()函数里调用了this函数,所以没有super函数,但B(String name)函数有super()。

8.9 super 关键字

8.9.1 基本介绍
super 代表父类的引用,用于访问父类的属性、方法、构造器。

8.9.2 基本语法
在这里插入图片描述
8.9.3 super 给编程带来的便利/细节
在这里插入图片描述
8.9.4 super 和 this 的比较
在这里插入图片描述
8.10 方法重写/覆盖(override)

8.10.1 基本介绍
在这里插入图片描述
8.10.3 注意事项和使用细节
在这里插入图片描述
8.10.4 课堂练习
在这里插入图片描述
8.11 面向对象编程-多态

8.11.1 先看一个问题
在这里插入图片描述
8.11.2 多[多种]态[状态]基本介绍
方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的。

8.11.3 多态的具体体现

  1. 方法的多态
    重写和重载就体现多态

  2. 对象的多态 (核心,困难,重点)
    在这里插入图片描述

package com.hspedu.poly_.objectpoly_; 
public class Animal { 
	public void cry() { 
		System.out.println("Animal cry() 动物在叫...."); 
	} 
}
package com.hspedu.poly_.objectpoly_; 
public class Cat extends Animal { 
	public void cry() { 
		System.out.println("Cat cry() 小猫喵喵叫..."); 
	} 
}
package com.hspedu.poly_.objectpoly_; 
public class Dog extends Animal {
	public void cry() { 
		System.out.println("Dog cry() 小狗汪汪叫..."); 
	} 
}
package com.hspedu.poly_.objectpoly_; 
public class PolyObject { 
	public static void main(String[] args) { 
		//体验对象多态特点 
		//animal 编译类型就是 Animal , 运行类型 Dog 
		Animal animal = new Dog(); 
		//因为运行时 , 执行到该行时,animal 运行类型是 Dog,所以 cry 就是 Dog 的 cry 
		animal.cry(); //小狗汪汪叫 
		//animal 编译类型 Animal,运行类型就是 Cat 
		animal = new Cat(); 
		animal.cry(); //小猫喵喵叫 
	} 
}

8.11.5 多态注意事项和细节讨论
在这里插入图片描述

package com.hspedu.poly_.detail_; 
public class Animal { 
	String name = "动物"; 
	int age = 10; 
	public void sleep(){ 
		System.out.println("睡"); 
	}
	public void run(){ 
		System.out.println("跑");
	}
	public void eat(){ 
		System.out.println("吃"); 
	}
	public void show(){ 
		System.out.println("hello,你好"); 
	} 
}
package com.hspedu.poly_.detail_; 
public class Cat extends Animal { 
	public void eat(){//方法重写 
		System.out.println("猫吃鱼"); 
	}
	public void catchMouse(){//Cat 特有方法 
		System.out.println("猫抓老鼠"); 
	} 
}
package com.hspedu.poly_.detail_; 
public class Dog extends Animal {//Dog 是 Animal 的子类 
}
package com.hspedu.poly_.detail_; 
public class PolyDetail {
	public static void main(String[] args) { 
		//向上转型: 父类的引用指向了子类的对象 
		//语法:父类类型引用名 = new 子类类型(); 
		Animal animal = new Cat(); 
		Object obj = new Cat();//可以吗? 可以 Object 也是 Cat 的父类 
		//向上转型调用方法的规则如下: 
		//(1)可以调用父类中的所有成员(需遵守访问权限) 
		//(2)但是不能调用子类的特有的成员 
		//(#)因为在编译阶段,能调用哪些成员,是由编译类型来决定的 
		//animal.catchMouse();错误 
		//(4)最终运行效果看子类(运行类型)的具体实现, 即调用方法时,按照从子类(运行类型)开始查找方法 
		//,然后调用,规则我前面我们讲的方法调用规则一致。 
		animal.eat();//猫吃鱼.. 
		animal.run();//跑 
		animal.show();//hello,你好 
		animal.sleep();//睡 
		
		//老师希望,可以调用 Cat 的 catchMouse 方法 
		//多态的向下转型 
		//(1)语法:子类类型 引用名 =(子类类型)父类引用; 
		//问一个问题? cat 的编译类型 Cat,运行类型是 Cat 
		Cat cat = (Cat) animal; 
		cat.catchMouse();//猫抓老鼠 
		//(2)要求父类的引用必须指向的是当前目标类型的对象
		Dog dog = (Dog) animal; //可以吗? 
		System.out.println("ok~~"); 
	} 
}

向下转型图解:
在这里插入图片描述
animal本来就指向cat对象,所以对animal向下转型为cat是没有问题的,用cat类型指向cat对象。

属性没有重写之说!属性的值看编译类型:

package com.hspedu.poly_.detail_; 
public class PolyDetail02 { 
	public static void main(String[] args) { 
		//属性没有重写之说!属性的值看编译类型 
		Base base = new Sub();//向上转型 
		System.out.println(base.count);// ? 看编译类型 10 
		Sub sub = new Sub(); 
		System.out.println(sub.count);//? 20 
	} 
}
class Base { //父类 
	int count = 10;//属性 
}
class Sub extends Base {//子类 
	int count = 20;//属性 
}

instanceOf 比较操作符,用于判断对象的运行类型是否为 XX 类型或 XX 类型的子类型:

package com.hspedu.poly_.detail_; 
public class PolyDetail03 { 
	public static void main(String[] args) { 
		BB bb = new BB(); 
		System.out.println(bb instanceof BB);// true 
		System.out.println(bb instanceof AA);// true 
		//aa 编译类型 AA, 运行类型是 BB 
		//BB 是 AA 子类 
		AA aa = new BB();
		System.out.println(aa instanceof AA); 
		System.out.println(aa instanceof BB); 
		Object obj = new Object(); 
		System.out.println(obj instanceof AA);//false 
		String str = "hello"; 
		//System.out.println(str instanceof AA); 
		System.out.println(str instanceof Object);//true 
	} 
}
class AA {} //父类
class BB extends AA {}//子类

8.11.6 课堂练习
在这里插入图片描述
8.11.7 java 的动态绑定机制(非常非常重要.)
在这里插入图片描述

package com.hspedu.poly_.dynamic_; 
public class DynamicBinding { 
	public static void main(String[] args) { 
		//a 的编译类型 A, 运行类型 B 
		A a = new B();//向上转型 
		System.out.println(a.sum());//?40 -> 30 
		System.out.println(a.sum1());//?30-> 20 
	} 
}
class A {//父类 
	public int i = 10; 
	//动态绑定机制: 
	public int sum() {//父类 sum() 
		return getI() + 10;//20 + 10
	}
	public int sum1() {//父类 sum1() 
		return i + 10;//10 + 10 
	}
	public int getI() {//父类 getI 
		return i; 
	} 
}
class B extends A {//子类 
	public int i = 20; 
//  public int sum() { 
// 		return i + 20; 
// 	}
	public int getI() {//子类 getI() 
		return i; 
	} 
// 	public int sum1() { 
// 		return i + 10; 
// 	} 
}

8.11.8 多态的应用
在这里插入图片描述

package com.hspedu.poly_.polyarr_; 
public class PloyArray { 
	public static void main(String[] args) { 
		//应用实例:现有一个继承结构如下:要求创建 1 个 Person 对象、 
		// 2 个 Student 对象和 2 个 Teacher 对象, 统一放在数组中,并调用每个对象 say 方法 
		Person[] persons = new Person[5]; 
		persons[0] = new Person("jack", 20); 
		persons[1] = new Student("mary", 18, 100); 
		persons[2] = new Student("smith", 19, 30.1); 
		persons[3] = new Teacher("scott", 30, 20000); 
		persons[4] = new Teacher("king", 50, 25000); 
		//循环遍历多态数组,调用 say 
		for (int i = 0; i < persons.length; i++) { 
			//老师提示: person[i] 编译类型是 Person ,运行类型是是根据实际情况由 JVM 来判断 
			System.out.println(persons[i].say());//动态绑定机制 
			//这里使用 类型判断 + 向下转型. 
			if(persons[i] instanceof Student) {//判断 person[i] 的运行类型是不是 Student 
				Student student = (Student)persons[i];//向下转型 
				student.study(); //小伙伴也可以使用一条语句 ((Student)persons[i]).study(); 
			} else if(persons[i] instanceof Teacher) { 
				Teacher teacher = (Teacher)persons[i]; 
				teacher.teach();
			} else if(persons[i] instanceof Person){ 
				//
			} else {
				System.out.println("你的类型有误, 请自己检查..."); 
			} 
		} 
	} 
}

8.12 Object 类详解

8.12.1 equals 方法
在这里插入图片描述
查看jdk源码之前需要配置如下,不过系统已经默认自动帮你配置了:
在这里插入图片描述
8.12.2 如何重写 equals 方法
应用实例: 判断两个 Person 对象的内容是否相等,如果两个 Person 对象的各个属性值都一样,则返回 true,反之 false。

package com.hspedu.object_; 
public class EqualsExercise01 { 
	public static void main(String[] args) { 
		Person person1 = new Person("jack", 10, '男'); 
		Person person2 = new Person("jack", 20, '男'); 
		System.out.println(person1.equals(person2));//假 
	} 
}
//判断两个 Person 对象的内容是否相等, 
//如果两个 Person 对象的各个属性值都一样,则返回 true,反之 false 
class Person{ //extends Object 
	private String name; 
	private int age; 
	private char gender; 
	//重写 Object 的 equals 方法 
	public boolean equals(Object obj) { 
		//判断如果比较的两个对象是同一个对象,则直接返回 true 
		if(this == obj) { 
			return true; 
		}
		//类型判断 
		if(obj instanceof Person) {//是 Person,我们才比较
		//进行 向下转型, 因为我需要得到 obj 的 各个属性 
		Person p = (Person)obj; 
		return this.name.equals(p.name) && this.age == p.age && this.gender == p.gender; }
		//如果不是 Person ,则直接返回 false 
		return false; 
	}
}

在这里插入图片描述
在这里插入图片描述
8.12.4 hashCode 方法
在这里插入图片描述
在这里插入图片描述
8.12.5 toString 方法
在这里插入图片描述

package com.hspedu.object_; 
public class ToString_ { 
	public static void main(String[] args) { 
		/*
			Object 的 toString() 源码 
			(1)getClass().getName() 类的全类名(包名+类名 ) 
			(2)Integer.toHexString(hashCode()) 将对象的 hashCode 值转成 16 进制字符串 
			public String toString() { 
				return getClass().getName() + "@" + Integer.toHexString(hashCode()); 
			}
		*/ 
		Monster monster = new Monster("小妖怪", "巡山的", 1000); 
		System.out.println(monster.toString() + " hashcode=" + monster.hashCode()); 
		System.out.println("==当直接输出一个对象时,toString 方法会被默认的调用=="); 
		System.out.println(monster); //等价 monster.toString()
	} 
}
class Monster { 
	private String name; 
	private String job; 
	private double sal; 
	public Monster(String name, String job, double sal) { 
		this.name = name; 
		this.job = job; 
		this.sal = sal; 
	}
	//重写 toString 方法, 输出对象的属性 
	//使用快捷键即可 alt+insert -> toString 
	@Override 
	public String toString() { //重写后,一般是把对象的属性值输出,当然程序员也可以自己定制 
		return "Monster{" + "name='" + name + '\'' + 
			", job='" + job + '\'' + 
			", sal=" + sal + 
			'}'; 
	}
	@Override
	protected void finalize() throws Throwable { 
		System.out.println("fin.."); 
	} 
}

8.12.6 finalize 方法
在这里插入图片描述

package com.hspedu.object_; 
//演示 Finalize 的用法 
public class Finalize_ { 
	public static void main(String[] args) { 
		Car bmw = new Car("宝马"); 
		//这时 car 对象就是一个垃圾,垃圾回收器就会回收(销毁)对象, 在销毁对象前,会调用该对象的 finalize 方法 
		//程序员就可以在 finalize 中,写自己的业务逻辑代码(比如释放资源:数据库连接,或者打开文件..) 
		//如果程序员不重写 finalize,那么就会调用 Object 类的 finalize, 即默认处理
		//如果程序员重写了 finalize, 就可以实现自己的逻辑 
		bmw = null; 
		System.gc();//主动调用垃圾回收器 
		System.out.println("程序退出了...."); 
	} 
}
class Car { 
	private String name; 
	//属性, 资源。。 
	public Car(String name) { 
		this.name = name; 
	}
	//重写 finalize 
	@Override 
	protected void finalize() throws Throwable { 
		System.out.println("我们销毁 汽车" + name ); 
		System.out.println("释放了某些资源..."); 
	} 
}

8.13 断点调试(debug)

8.13.1 一个实际需求
在这里插入图片描述
8.13.3 断点调试的快捷键
在这里插入图片描述
小技巧:将光标放在某个变量上,可以看到最新的数据。
老韩小技巧:断点可以在 debug 过程中,动态的下断点

8.15 本章作业
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

韩顺平 2021零基础学Java 学习笔记(1)(自用) 的相关文章

  • Spring Security 通过并发登录尝试将用户锁定

    我是安全新手 遇到了一个问题 该问题导致用户帐户被锁定 只有重新启动应用程序才能修复它 我有一个带有 spring security 4 0 2 RELEASE 应用程序的 spring boot 1 3 0 BUILD SNAPSHOT
  • JavaFX Platform.runLater 的使用以及从不同线程访问 UI

    我有几个问题Platform runLater 我有一个 JavaFX 应用程序类 在这个类中 我运行一个线程 该线程从网络套接字读取数据 现在当我创建一个新的Stage在线程内部 系统抛出异常 JavaFX 事件调度程序线程和我的网络读取
  • 如何在Java 8中实现Elvis运算符?

    我有一个经典的 Elvis 运算符 案例 其中我调用每个可能返回 null 的方法并将它们链接在一起 thing nullableMethod1 a nullableMethod2 b nullableMethod3 在 Java 8 中
  • Javadoc 1.5 和 1.6 中缺少 enum.valueOf(String name)

    这可能是一个愚蠢的问题 但我正在使用该方法enum valueOf String name 那里没问题 只是当我检查 javadoc 以了解有关此方法的更多信息时 我找不到它 有javadoc用于valueOf Class
  • 静态方法的 Java 内存模型

    我来自操作系统和 C 语言背景 在代码编译时 世界很简单 需要处理和理解堆栈 堆文本部分等 当我开始学习 Java 时 我确实了解 JVM 和垃圾收集器 我对静态方法感到很有趣 根据我的理解 类的所有实例都会在堆中创建 然后被清理 但是 对
  • 使用 Spring Data REST 处理自定义异常 (i18n)

    我正在使用 Spring Boot 1 5 4 和 Spring JPA Spring Data REST HATEOAS 我正在寻找一种最佳实践 Spring 方式 来自定义异常 Spring Data REST 正在管理添加 i18n
  • 如何识别 Java 中的不可变对象

    在我的代码中 我正在创建一个对象集合 这些对象将由各种线程以只有在对象不可变的情况下才安全的方式访问 当尝试将新对象插入到我的集合中时 我想测试它是否是不可变的 如果不是 我将抛出异常 我能做的一件事是检查一些众所周知的不可变类型 priv
  • Java 唤醒休眠线程

    我阅读了其他帖子 但没有找到我正在寻找的确切答案 所以我希望有人能给出一些澄清 我有一个将运行一段时间的程序 我有一些在后台运行的线程来执行各种任务 为了简单起见 让我们考虑 3 个线程 ThreadA每 10 秒执行一次任务 其中Thre
  • 支持通过 OAuth 进行 Facebook/Twitter 身份验证的 CAS 服务器

    我正在寻找一个支持 Facebook Twitter 通过 OAuth 进行单点登录身份验证的 CAS 服务器 我检查过 JASIG CAS 服务器 但它看起来不支持它们 我的 java web 应用程序基于 Spring Security
  • Java 泛型:如何为泛型类型指定类类型?

    我有一个 POJO 指定为 MyClass u where U是泛型类型参数 我正在尝试编写一个接受类引用的实用方法Class u
  • 如何制作无限的jscrollpane?

    我之前已经实现过拖动滚动 但是创建无限滚动窗格的最佳方法是什么 当然不会有任何滚动条 我将实现拖动滚动 我想做的是在无限表面上实现动态加载 EDIT 当然 它实际上不会是无限的 我想问如何伪造它 您可以执行以下操作 AdjustmentCl
  • 不要模拟值对象:过于通用的规则,没有解释

    以下是 Mockito 单元测试框架的引用 不要模拟值对象 为什么有人会想要这样做呢 因为实例化对象太痛苦了 gt 无效 原因 如果创造新的装置太困难 那就是一个迹象 代码可能需要一些认真的重构 另一种方法是创建 价值对象的构建者 有一些工
  • 在 eclipse 之外将 Spring MVC 应用程序部署到 tomcat 的幕后会发生什么?

    我猜想使用像 eclipse 这样很棒的 IDE 的一个缺点是你会忽略应用程序幕后发生的事情 我是一名 Ruby 开发人员 所以不是一名 Java 老手 所以我一直在用 java 编写一个项目 并使用 spring 框架进行 IOC 和 M
  • 是否可以为 azure blob 存储中的给定目录生成具有写入权限的 SAS(共享访问签名)

    我们的 blob 存储帐户结构 容器名称 simple 在这个容器内我们有 blob aa one zip aa two zip bb ss zip bb dd zip 是否可以生成对aa 目录 有写权限 但对bb 目录 没有访问权限的SA
  • 在Java中多次读取System.in会导致IOException?

    我正在尝试创建一个小命令行游戏来强化我在过去几个月中在 Java 中学到的一些东西 我正在尝试创建一个名为 readInput 的方法 它返回一个我可以一次又一次调用的字符串 第一次它工作正常 但第二次它会导致 IO Exception 如
  • 无法映射 ftl 文件中的 jsonRequest 属性

    我想在 FTL 文件中映射下面的 json 文件市场和子市场字段 但是当我尝试下面的代码时 它没有映射 有人可以帮助我吗 我从 2 天开始就无法映射它 Json请求 ProcessOrderRequest prevalidationMode
  • 找不到符号assertEquals

    我正在尝试为计算器编写第一个单元测试 但 NetBeans 说它找不到该符号assertEquals和注释 Test 我应该包括一些东西吗 我正在使用 NetBeans 7 3 1 和 W7 package calculator impor
  • Google Place Api:来自此 Android 客户端应用程序 com.package.name 的请求被阻止

    我在用PlaceAutocompleteFragment当我单击搜索字段 PlaceAutocompleteFragment 对话框消失时 我收到此错误 errors domain global re ason forbidden mess
  • H2 - (相当)长的 INSERT 失败,错误 42000

    H2 内存中 插入 错误 42000 尝试过版本 1 4 196 1 4 197 1 4 199 我还尝试在 H2 服务器 本地 上执行 INSERT 也失败 给出错误的行 抱歉 但出于安全原因 我无法生成更多 INSERT INTO tb
  • 我找不到 IntelliJ 快捷方式

    我使用 vim 一段时间 我知道有一个 intellij vim 插件 我很好奇内置的 IntelliJ 文本导航存在什么 如何打开实时模板来创建模板 如何查看以 tr 开头的现有模板列表 如何进行全局搜索并在当前文档中进行搜索 然后转到下

随机推荐

  • Qt 插入Label到指定位置

    QLabel label new QLabel this label gt setFrameStyle QFrame Panel QFrame Sunken label gt setText first line nsecond line
  • [C++]中介者模式

    中介者模式 Mediator Pattern 是用来降低多个对象和类之间的通信复杂性 这种模式提供了一个中介类 该类通常处理不同类之间的通信 并支持松耦合 使代码易于维护 中介者模式属于行为型模式 github源码路径 https gith
  • VSCode配置C语言环境(完整版)

    基本步骤 要在VSCode中配置C语言环境 我们首先可能要一个VSCode 废话 所以先下载安装一个VSCode 然后肯定需要相关插件 因为VSCode不能直接拿来写C 然后任何语言的程序在运行前都需要编译 那还需要一个编译器 很可惜VSC
  • (Python)蚁群算法解决旅行商问题(ACO-TSP)

    蚁群算法又称蚂蚁算法 容易与其他算法相结合 但也存在收敛速度慢 容易陷入局部最优等缺点 coding utf 8 import random import copy import time import sys import math im
  • 【刷题】华为笔试面试机考 [HJ29] - 字符串加解密

    题目地址 点击跳转 题目描述 1 对输入的字符串进行加解密 并输出 2 加密方法为 当内容是英文字母时则用该英文字母的后一个字母替换 同时字母变换大小写 如字母a时则替换为B 字母Z时则替换为a 当内容是数字时则把该数字加1 如0替换1 1
  • 【性能测试】第五篇

    JMeter环境安装 安装JDK 1 JDK下载 官网下载 http www oracle com 提示 下载时注意电脑系统是32位还是64位 桌面 计算机 右击 属性 查看 系统类型 2 安装JDK 双击安装包进行安装 所有步骤选择默认选
  • AVL树的插入操作(四种情况)

    目录 前言 一 AVL树简介 平衡因子bf 二 AVL树的插入操作 不包含重复值 1 找到要插入的位置 和普通的二叉搜索树一样 2 平衡化 情况1 右旋 Single Right Rotation 情况2 左旋 Single Left Ro
  • ubuntu shell实现加减乘除

    bin sh a 8 b 4 c expr a b 乘法 c expr a b 加法 c expr a b 减法 c expr a b 除法
  • 【Windows】 谷歌翻译停服后,chrome无法自动翻译?解决办法来了~

    早前蓝点网提到谷歌翻译中国版和谷歌地图中国版同时停服 此次停服也影响到谷歌浏览器翻译功能的使用 谷歌给出的官方回应是谷歌翻译和谷歌地图的中国版使用率都太低 既然使用率太低那直接停服也情有可原 笑笑 只是谷歌浏览器内置的翻译功能也需要调用谷歌
  • LeetCode每日一题:1462. 课程表 IV(2023.9.12 C++)

    目录 1462 课程表 IV 题目描述 实现代码与解析 拓扑排序 原理思路 1462 课程表 IV 题目描述 你总共需要上 numCourses 门课 课程编号依次为 0 到 numCourses 1 你会得到一个数组 prerequisi
  • KVM-6、virsh 命令及功能详解

    1 虚拟机管理操作 attach device 从XML文件附加设备 attach disk 附加磁盘设备 attach interface 连接网络接口 autostart 自动启动一个域 blkdeviotune 设置或查询块设备I O
  • IDEA报错Project lease-web: there is circular dependency between tests of ‘service-util‘ module, tests

    项目场景 当我创建多个模块时 为了模块化管理利于模块复用 我一层包一层 问题描述 例如 当我要运行的时候发现报错 Project lease web there is circular dependency between tests of
  • Linux 音视频开发杂记之二-使用FFmpeg

    FFmpeg简介 FFmpeg是一套可以用来记录 转换数字音频 视频 并能将其转化为流的开源计算机程序 采用LGPL或GPL许可证 它提供了录制 转换以及流化音视频的完整解决方案 ubuntu下FFmpeg下载 编译并安装 1 基础依赖库安
  • 动态规划基础之挖金矿问题

    问题 有一个国家发现了5座金矿 每座金矿的黄金储量不同 需要参与挖掘的工人数也不同 情况如下图 金矿编号 黄金储量 需要人数 1 500 5 2 200 3 3 300 4 4 350 3 5 400 5 参与挖矿工人的总数是10人 每座金
  • 点云目标检测 国内外现状 2000字

    国内外现状近年来 点云目标检测技术受到了越来越多的关注 其中包括传统的统计学习方法和深度学习方法 由于深度学习方法的出现 点云目标检测研究取得了长足的进步 首先 深度学习方法大大提高了点云目标检测的准确率 其次 深度学习方法也大大简化了点云
  • C++:防止int32溢出--以反转数字为例

    int32溢出 在C 等语言中int类型的整数占4个字节 一般而言 而一个字节是8bit 所以int型可表示32位的整数 又因为int可以表示负数 所以int的范围是 2 31 2 31 231
  • Unity3D之UI按键绑定事件(六)

    六 通过unity系统自带接口和观察者模式绑定按键事件 UI UGUI 如何判断UI元素被点击时是鼠标哪个按键 五 中我们可以根据eventData pointerId来监听是我们按下的是鼠标左键还是右键 通过前面几部分学习我们已经实现对U
  • 字符设备驱动之异步通知

    一 应用程序主动的去查询或 read 1 查询方式 很占资源 2 中断机制 虽然有休眠 但在没有按键按下时 read 3 poll 机制 指定超时时间 以上都是 应用程序 主动去读或查询 二 异步通知 有按键按下了 驱动程序来提醒 触发 应
  • 18.函数subplot2grid():让子区跨越固定的网格布局

    文章目录 1 subplot2grid 的使用方法 2 模块gridspec中的类GridSpec的使用方法 subplot2grid 函数的rowspan和colspan参数可以让子区跨越固定的网格布局的多个行和列 实现不同的子区布局 比
  • 韩顺平 2021零基础学Java 学习笔记(1)(自用)

    目录 第 2 章 Java 概述 第 3 章 变量 第 4 章 运算符 第 5 章 程序控制结构 第 6 章 数组 排序和查找 第 7 章 面向对象编程 基础部分 第 8 章 面向对象编程 中级部分 第 2 章 Java 概述 2 1 Ja