公司门户网站及oa系统建设的请示,wordpress多板块,温州多语言网站建设,超简单手工小制作循序渐进学Java 零基础 -韩顺平
第 1 章 内容介绍 1 1.1 本套 JAVA 课程内容 1 1.1.1 课程的三个阶段 1 1.1.2 关于课程的说明 1 1.1.3 课程特色 2 1.2 JAVA 就业方向 2 1.3 JAVA 开发场景举例 1-SSM 3 1.4 JAVA 开发场景举例 2#xff1a;ANDROID 核心代码 3 1.5 JAVA 开发场…循序渐进学Java 零基础 -韩顺平
第 1 章 内容介绍 1 1.1 本套 JAVA 课程内容 1 1.1.1 课程的三个阶段 1 1.1.2 关于课程的说明 1 1.1.3 课程特色 2 1.2 JAVA 就业方向 2 1.3 JAVA 开发场景举例 1-SSM 3 1.4 JAVA 开发场景举例 2ANDROID 核心代码 3 1.5 JAVA 开发场景举例 3大数据-HADOOP 4 1.6 JAVA 的应用领域 4 1.6.1 企业级应用 4 1.6.2 Android 平台应用 5 1.6.3 移动领域应用 5 第 2 章 JAVA 概述 7 2.1 什么是程序 7 2.2 JAVA 诞生小故事 7 2.3 JAVA 技术体系平台 8 2.4 JAVA 重要特点 8 2.5 JAVA 的开发工具 9 2.5.1 工具选择 10 2.6 JAVA 运行机制及运行过程 10 2.6.1 Java 语言的特点跨平台性 10 2.6.2 Java 核心机制-Java 虚拟机 [JVM java virtual machine] 11 2.7 什么是 JDKJRE 12 2.7.1 JDK 基本介绍 12 2.7.2 JRE 基本介绍 12 2.7.3 JDK、JRE 和 JVM 的包含关系 12 2.8 下载、安装 JDK 12 2.9 配置环境变量 PATH 13 2.9.1 为什么要配置 path 13 2.9.2 配置环境变量 path 的步骤 13 2.10 安装 JDK 的练习 14 2.10.1 请同学们安装好 JDK配置好 path 环境变量。可以在控制台下正确的执行, (10min) 14 2.10.2 环境变量配置细节说明: 14 2.11 JAVA 快速入门 14 2.11.1 需求说明 15 2.11.2 开发步骤 15 2.11.3 运行原理示意图 15
2.12 JAVA 开发快速入门 15 2.13 JAVA 开发注意事项和细节说明 17 2.14 老韩聊: 如何快速掌握技术或知识点 18 2.15 JAVA 转义字符 19 2.15.1 Java 常用的转义字符 19 2.15.2 说明 19 2.15.3 课堂练习 21 2.16 初学 JAVA 易犯错误 21 2.17 注释(COMMENT) 22 2.17.1 介绍 22 2.17.2 Java 中的注释类型 23 2.17.3 单行注释 23 2.17.4 多行注释 23 2.17.5 使用细节 23 2.17.6 文档注释 23 2.17.7 代码演示 24 2.18 JAVA 代码规范 26 2.19 DOS 命令(了解) 26 2.19.1 DOS 介绍 26 2.19.2 相关的知识补充: 相对路径 绝对路径 27 2.19.3 常用的 dos 命令 28 2.20 本章作业 28 第 3 章 变量 29 3.1 为什么需要变量 29 3.1.1 一个程序就是一个世界 29 3.1.2 变量是程序的基本组成单位 29 3.1.3 简单的原理示意图 30 3.2 变(变化)量(值)的介绍 30 3.2.1 概念 30 3.2.2 变量使用的基本步骤 30 3.3 变量快速入门 31 3.4 变量使用注意事项 32 3.5 程序中 号的使用 33 3.6 数据类型 33 3.7 整数类型 34 3.7.1 基本介绍 34 3.7.2 案例演示 34 3.7.3 整型的类型 34
3.7.4 整型的使用细节 IntDetail.java 35 3.8 浮点类型 37 3.8.1 基本介绍 37 3.8.2 案例演示 37 3.8.3 浮点型的分类 37 3.8.4 说明一下 37 3.8.5 浮点型使用细节 FloatDetail.java 37 3.9 JAVA API 文档 40 3.10 字符类型(CHAR) 41 3.10.1 基本介绍 41 3.10.2 案例演示 Char01.java 41 3.10.3 字符类型使用细节 41 3.11 ASCII 码介绍(了解) 44 3.12 UNICODE 编码介绍(了解) 44 3.13 UTF-8 编码介绍(了解) 44 3.14 布尔类型BOOLEAN 44 3.15 基本数据类型转换 46 3.15.1 自动类型转换 46 3.15.2 自动类型转换注意和细节 46 3.15.3 强制类型转换 49 3.15.4 强制类型转换细节说明 49 3.16 基本数据类型转换-练习题 50 3.17 基本数据类型和 STRING 类型的转换 51 3.17.1 介绍和使用 51 3.17.2 注意事项 53 3.18 本章作业 54 第 4 章 运算符 56 4.1 运算符介绍 56 4.1.1 运算符介绍 56 4.2 算术运算符 56 4.2.1 介绍 56 4.2.2 算术运算符一览 56 4.2.3 案例演示 56 4.2.4 细节说明 58 4.2.5 面试题 59 4.2.6 自增 自减课堂练习, 看看输出什么 59 4.2.7 课堂练习 2 60 4.3 关系运算符(比较运算符) 62
4.3.1 介绍 62 4.3.2 关系运算符一览 62 4.3.3 案例演示 63 4.3.4 细节说明 64 4.4 逻辑运算符 64 4.4.1 介绍 64 4.4.2 逻辑运算符一览 64 4.4.3 和 基本规则 65 4.4.4 和 案例演示 65 4.4.5 和 使用区别 66 4.4.6 || 和 | 基本规则 67 4.4.7 || 和 | 案例演示 67 4.4.8 || 和 | 使用区别 68 4.4.9 ! 取反 基本规则 68 4.4.10 ! 案例演示 69 4.4.11 ^ 案例演示 69 4.4.12 练习题 1 请写出每题的输出结果 70 4.4.13 练习题 2 请写输出结果 70 4.5 赋值运算符 70 4.5.1 介绍 70 4.5.2 赋值运算符的分类 71 4.5.3 案例演示 71 4.5.4 赋值运算符特点 71 4.6 三元运算符 72 4.6.1 基本语法 72 4.6.2 案例演示 TernaryOperator.java 73 4.6.3 使用细节 TernaryOperatorDetail.java 73 4.6.4 课堂练习 74 4.7 运算符优先级 76 4.8 标识符的命名规则和规范 77 4.8.1 判断下面变量名是否正确 77 4.8.2 标识符命名规范[更加专业] 77 4.9 关键字 78 4.10 保留字 79 4.10.1 介绍 79 4.11 键盘输入语句 79 4.11.1 介绍 79 4.11.2 步骤 79 4.11.3 案例演示 80
4.12 进制(程序员的基本功) 81 4.12.1 进制介绍 81 4.12.2 举例说明 BinaryTest.java 81 4.13 进制的图示 82 4.14 进制的转换(基本功) 83 4.14.1 进制转换的介绍 83 4.15 二进制转换成十进制示例 84 4.16 八进制转换成十进制示例 84 4.17 十六进制转换成十进制示例 84 4.18 十进制转换成二进制 84 4.19 十进制转换成八进制 85 4.20 十进制转换成十六进制 85 4.21 二进制转换成八进制 86 4.22 二进制转换成十六进制 86 4.23 八进制转换成二进制 86 4.24 十六进制转换成二进制 86 4.25 位运算的思考题 87 4.26 二进制在运算中的说明 87 4.27 原码、反码、补码(重点 难点) 88 4.28 位运算符 88 4.28.1 java 中有 7 个位运算(、|、^、~、、和 ) 88 4.28.2 还有 3 个位运算符 、 和 , 运算规则: 88 4.28.3 应用案例 BitOperator02.java 89 4.28.4 完成前面的案例 89 4.29 本章作业 89 第 5 章 程序控制结构 91 5.1 程序流程控制介绍 91 5.2 顺序控制 91 5.3 分支控制 IF-ELSE 91 5.3.1 分支控制 if-else 介绍 91 5.3.2 单分支 92 5.4 双分支 93 5.4.1 双分支 95 5.4.2 单分支和双分支练习题 96 5.4.3 多分支 98 多分支的流程图(重要!) 99 5.4.4 多分支 99 5.5 嵌套分支 102
5.5.1 基本介绍 102 5.5.2 基本语法 102 5.5.3 应用案例 102 5.5.4 应用案例 2, 一定自己做 104 5.6 SWITCH 分支结构 104 5.6.1 基本语法 104 5.6.2 流程图 105 5.6.3 快速入门 105 5.6.4 switch 注意事项和细节讨论 107 5.6.5 switch 课堂练习(学员先做) 108 5.6.6 switch 和 if 的比较 112 5.7 FOR 循环控制(!!!) 112 5.7.1 看一个实际需求 113 5.7.2 基本语法 113 5.7.3 for 循环执行流程分析 113 5.7.4 注意事项和细节说明 114 5.7.5 for 循环练习题(学员先做) 115 5.8 WHILE 循环控制 117 5.8.1 基本语法 117 5.8.2 while 循环执行流程分析 118 5.8.3 注意事项和细节说明 120 5.8.4 课堂练习题[学员先做] 120 5.9 DO WHILE 循环控制… 121 5.9.1 基本语法 121 5.9.2 老韩说明: 122 5.9.3 do while 循环执行流程分析…122 5.9.4 注意事项和细节说明 123 5.9.5 课堂练习题【学员先做】 123 5.10 多重循环控制(难点! 重点!) 126 5.10.1 介绍 126 5.10.2 多重循环执行步骤分析 126 5.10.3 应用实例 127 5.10.4 经典的打印金字塔 130 5.11 跳转控制语句-BREAK 133 5.11.1 看下面一个需求 133 5.11.2 基本介绍 133 5.11.3 基本语法 133 5.11.4 以 while 使用 break 为例,画出示意图 133 5.11.5 快速入门: 134
5.11.6 注意事项和细节说明 134 5.11.7 课堂练习题 134 5.12 跳转控制语句-CONTINUE 137 5.12.1 基本介绍 137 5.12.2 基本语法 138 5.12.3 以 while 使用 continue 为例,画出示意图 138 5.12.4 快速入门案例 138 5.12.5 细节案例分析和说明 ContinueDetail.java 139 5.13 跳转控制语句-RETURN 139 5.14 本章作业 140 第 6 章 数组、排序和查找 142 6.1 为什么需要数组 142 6.1.1 数组介绍 142 6.1.2 数组快速入门 142 6.2 数组的使用 145 6.2.1 使用方式 2-动态初始化 147 6.2.2 使用方式 3-静态初始化 147 6.3 数组使用注意事项和细节 147 6.4 数组应用案例 149 6.5 数组赋值机制 152 6.6 数组拷贝 152 6.7 数组反转 154 6.8 数组添加/扩容 157 6.9 排序的介绍 160 6.9.1 内部排序: 160 6.9.2 外部排序法 161 6.10 冒泡排序法 161 6.11 冒泡排序法 161 6.12 查找 167 6.12.1 介绍 167 6.12.2 案例演示 167 6.13 多维数组-二维数组 169 6.14 二维数组的使用 169 6.14.1 快速入门案例 169 6.14.2 使用方式 1: 动态初始化 171 6.14.3 使用方式 2: 动态初始化 173 6.14.4 使用方式 3: 动态初始化-列数不确定 173 6.14.5 使用方式 4: 静态初始化 175
6.14.6 案例 176 6.15 二维数组的应用案例 177 6.16 二维数组使用细节和注意事项 179 6.17 二维数组课堂练习 180 6.18 本章作业 180 第 7 章 面向对象编程(基础部分) 183 7.1 类与对象 183 7.1.1 看一个养猫猫问题 183 7.1.2 使用现有技术解决 Object01.java 183 7.1.3 现有技术解决的缺点分析 183 7.1.4 一个程序就是一个世界有很多事物(对象[属性, 行为]) 186 7.1.5 类与对象的关系示意图 186 7.1.6 类与对象的关系示意图 187 7.1.7 快速入门-面向对象的方式解决养猫问题 187 7.1.8 类和对象的区别和联系 187 7.1.9 对象在内存中存在形式(重要的)必须搞清楚。 188 7.1.10 属性/成员变量/字段 188 7.1.11 如何创建对象 191 7.1.12 如何访问属性 191 7.1.13 类和对象的内存分配机制 192 7.2 成员方法 193 7.2.1 基本介绍 193 7.2.2 成员方法快速入门 194 7.2.3 方法的调用机制原理(重要!-示意图!!!) 197 7.2.4 为什么需要成员方法 197 7.2.5 成员方法的好处 200 7.2.6 成员方法的定义 200 7.2.7 注意事项和使用细节 201 7.2.8 类定义的完善 207 7.2.9 课堂练习题 207 7.3 成员方法传参机制(非常非常重要) 209 7.3.1 基本数据类型的传参机制 210 7.3.2 引用数据类型的传参机制 211 7.3.3 成员方法返回类型是引用类型应用实例 215 7.4 方法递归调用(非常非常重要 比较难) 218 7.4.1 基本介绍 218 7.4.2 递归能解决什么问题? 218 7.4.3 递归举例 218
7.4.4 递归重要规则 221 7.4.5 课堂练习 221 7.4.6 递归调用应用实例-迷宫问题 224 7.4.7 递归调用应用实例-汉诺塔 230 7.4.8 递归调用应用实例-八皇后问题[同学们先尝试做后面老师评讲.] 232 7.5 方法重载(OVERLOAD) 233 7.5.1 基本介绍 233 7.5.2 重载的好处 233 7.5.3 快速入门案例 233 7.5.4 注意事项和使用细节 236 7.5.5 课堂练习题 236 7.6 可变参数 240 7.6.1 基本概念 240 7.6.2 基本语法 240 7.6.3 快速入门案例(VarParameter01.java) 240 7.6.4 注意事项和使用细节 242 7.6.5 课堂练习 243 7.7 作用域 245 7.7.1 基本使用 245 7.7.2 注意事项和细节使用 247 7.8 构造方法/构造器 249 7.8.1 看一个需求 250 7.8.2 基本语法 250 7.8.3 基本介绍 250 7.8.4 快速入门 250 7.8.5 注意事项和使用细节 252 7.8.6 课堂练习题 254 7.9 对象创建的流程分析 256 7.9.1 看一个案例 256 7.10 THIS 关键字 257 7.10.1 先看一段代码,并分析问题 257 7.10.2 深入理解 this 260 7.10.3 this 的注意事项和使用细节 261 7.10.4 this 的课堂案例 262 7.11 本章作业 263 第 8 章 面向对象编程(中级部分) 267 8.1 IDE(集成开发环境) -IDEA 267 8.1.1 IDEA 介绍 267
8.2 IDE(集成开发环境) -ECLIPSE 267 8.2.1 Eclipse 介绍 267 8.3 IDE(集成开发环境) -IDEA 的使用 267 8.3.1 IDEA 的安装 267 8.3.2 IDEA 的基本介绍和使用 268 8.3.3 IDEA 使用技巧和经验 268 8.3.4 课堂练习 269 8.3.5 IDEA 常用快捷键 270 8.3.6 模板/自定义模板 270 8.4 包 271 8.4.1 看一个应用场景 271 8.4.2 包的三大作用 271 8.4.3 包基本语法 271 8.4.4 包的本质分析(原理) 271 8.4.5 快速入门 271 8.4.6 包的命名 272 8.4.7 常用的包 272 8.4.8 如何引入包 272 8.4.9 注意事项和使用细节 274 8.5 访问修饰符 275 8.5.1 基本介绍 275 8.5.2 4 种访问修饰符的访问范围 275 8.5.3 使用的注意事项 275 8.6 面向对象编程三大特征 278 8.6.1 基本介绍 278 8.6.2 封装介绍 278 8.6.3 封装的理解和好处 278 8.6.4 封装的实现步骤 (三步) 278 8.7 快速入门案例 279 8.7.1 将构造器和 setXxx 结合 282 8.7.2 课堂练习 283 8.8 面向对象编程-继承 287 8.8.1 为什么需要继承 287 8.8.2 继承基本介绍和示意图 287 8.8.3 继承的基本语法 288 8.8.4 快速入门案例 288 8.8.5 继承给编程带来的便利 290 8.8.6 继承的深入讨论/细节问题 290 8.8.7 继承的本质分析(重要) 295
8.8.8 课堂练习 298 8.9 SUPER 关键字 303 8.9.1 基本介绍 303 8.9.2 基本语法 303 8.9.3 super 给编程带来的便利/细节 309 8.9.4 super 和 this 的比较 309 8.10 方法重写/覆盖(OVERRIDE) 309 8.10.1 基本介绍 309 8.10.2 快速入门 310 8.10.3 注意事项和使用细节 313 8.10.4 课堂练习 313 8.11 面向对象编程-多态 317 8.11.1 先看一个问题 317 8.11.2 多[多种]态[状态]基本介绍 322 8.11.3 多态的具体体现 322 8.11.4 多态快速入门案例 325 8.11.5 多态注意事项和细节讨论 326 8.11.6 课堂练习 331 8.11.7 java 的动态绑定机制(非常非常重要.) 331 8.11.8 多态的应用 334 8.12 OBJECT 类详解 344 8.12.1 equals 方法 344 8.12.2 如何重写 equals 方法 347 8.12.3 课堂练习题 350 8.12.4 hashCode 方法 352 8.12.5 toString 方法 353 8.12.6 finalize 方法 356 8.13 断点调试(DEBUG) 357 8.13.1 一个实际需求 358 8.13.2 断点调试介绍 358 8.13.3 断点调试的快捷键 358 8.13.4 断点调试应用案例 359 8.13.5 断点调试应用案例 359 8.13.6 断点调试课后练习 362 8.14 项目-零钱通 362 8.14.1 项目开发流程说明 362 8.14.2 项目需求说明 362 8.14.3 项目的界面 362 8.14.4 项目代码实现 363
8.14.5 项目代码实现改进 363 8.15 本章作业 363 第 9 章 项目-房屋出租系统 369 9.1 房屋出租系统-需求 369 9.1.1 项目需求说明 369 9.2 房屋出租系统-界面 369 9.2.1 项目界面 - 主菜单 369 9.2.2 项目界面- 新增房源 369 9.2.3 项目界面- 查找房源 369 9.2.4 项目界面- 删除房源 370 9.2.5 项目界面- 修改房源 370 9.2.6 项目界面- 房屋列表 370 9.2.7 项目界面- 退出系统 370 9.3 房屋出租系统-设计(!!) 371 9.4 房屋出租系统-实现 371 9.4.1 准备工具类 Utility提高开发效率 371 9.4.2 项目功能实现-完成 House 类 371 9.4.3 项目功能实现-显示主菜单和完成退出软件功能 372 9.4.4 项目功能实现-完成显示房屋列表的功能 372 9.4.5 项目功能实现-添加房屋信息的功能 372 9.4.6 项目功能实现-完成删除房屋信息的功能 373 9.4.7 项目功能实现-完善退出确认功能(课堂作业) 373 9.4.8 项目功能实现-完成根据 id 查找房屋信息的功能(课后作业) 374 9.4.9 项目功能实现-完成修改房屋信息的功能(课后作业) 374 第 10 章 面向对象编程(高级部分) 375 10.1 类变量和类方法 375 10.1.1 类变量-提出问题 375 10.1.2 传统的方法来解决 375 10.1.3 类变量快速入门 375 10.1.4 类变量内存布局 377 10.1.5 什么是类变量 378 10.1.6 如何定义类变量 378 10.1.7 如何访问类变量VisitStatic.java 379 10.1.8 类变量使用注意事项和细节讨论 StaticDetail.java 380 10.1.9 类方法基本介绍 381 10.1.10 类方法的调用 381 10.1.11 类方法应用案例 StaticMethod.java 381
10.1.12 类方法经典的使用场景 383 10.1.13 类方法使用注意事项和细节讨论 StaticMethodDetail.java 384 10.1.14 课堂练习 StaticExercise01.java 386 10.1.15 题 2(评讲)看看下面代码有没有错误,如果有错误就修改看看输出什么? 386 10.1.16 题 3(评讲)看看下面代码有没有错误,如果有错误就修改看看 total 等于多少 4? 387 10.2 理解 MAIN 方法语法 388 10.2.1 深入理解 main 方法 388 10.2.2 特别提示 389 10.2.3 案例演示 390 10.3 代码块 391 10.3.1 基本介绍 391 10.3.2 基本语法 391 10.3.3 代码块的好处和案例演示 392 10.3.4 代码块使用注意事项和细节讨论 CodeBlockDetail01.java 394 10.3.5 课堂练习题 CodeBlockExercise01.java 404 10.3.6 题 2下面的代码输出什么 405 10.4 单例设计模式 406 10.4.1 什么是设计模式 406 10.4.2 什么是单例模式 407 10.4.3 单例模式应用实例 407 10.4.4 饿汉式 VS 懒汉式 412 10.5 FINAL 关键字 412 10.5.1 基本介绍 412 10.5.2 final 使用注意事项和细节讨论 414 10.5.3 final 应用实例 418 10.6 抽象类 419 10.6.1 先看一个问题 Abstract01.java 419 10.6.2 解决之道-抽象类快速入门 421 10.6.3 抽象类的介绍 421 10.6.4 抽象类使用的注意事项和细节讨论 AbstractDetail01.java 421 10.6.5 抽象类使用的注意事项和细节讨论 AbstractDetail02.java 422 10.6.6 课堂练习题 AbstractExercise01.java 5min 练习 424 10.7 抽象类最佳实践-模板设计模式 428 10.7.1 基本介绍 428 10.7.2 模板设计模式能解决的问题 428 10.7.3 最佳实践 428 10.8 接口 432 10.8.1 为什么有接口 432 10.8.2 接口快速入门 432
10.8.3 基本介绍 435 10.8.4 深入讨论 435 10.8.5 注意事项和细节 439 10.8.6 课堂练习 442 10.8.7 实现接口 vs 继承类 443 10.8.8 接口的多态特性 445 10.8.9 课堂练习 InterfaceExercise02.java 450 10.9 内部类 451 10.9.1 基本介绍 451 10.9.2 基本语法 451 10.9.3 快速入门案例 452 10.9.4 内部类的分类 453 10.9.5 局部内部类的使用 LocalInnerClass.java 453 10.9.6 匿名内部类的使用(重要!!!) 455 10.9.7 匿名内部类的最佳实践 463 10.9.8 匿名内部类课堂练习 464 10.9.9 成员内部类的使用 467 10.9.10 静态内部类的使用 StaticInnerClass01.java 470 10.9.11 课堂测试题 472 10.10 卖油翁和老黄牛 473 第 11 章 枚举和注解 475 11.1 先看一个需求 475 11.2 分析问题 477 11.2.1 创建 Season 对象有如下特点 477 11.3 解决方案-枚举 477 11.4 枚举的二种实现方式 477 11.5 自定义类实现枚举-应用案例 477 11.6 自定义类实现枚举-小结 479 11.6.1 小结进行自定义类实现枚举有如下特点 479 11.7 ENUM 关键字实现枚举-快速入门 480 11.7.1 说明 480 11.7.2 enum 关键字实现枚举注意事项 482 11.8 ENUM 关键字实现枚举-课堂练习 483 11.9 ENUM 常 2 用方法说明 484 11.10 ENUM 常用方法应用实例 484 11.11 ENUM 实现接口 489 11.12 注解的理解 491 11.13 基本的 ANNOTATION 介绍 491
11.14 基本的 ANNOTATION 应用案例 491 11.14.1 Override 注解的案例 Override_.java 491 11.14.2 Deprecated 注解的案例 Deprecated_.java 494 11.14.3 SuppressWarnings 注解的案例 SuppressWarnings_.java 495 11.15 JDK 的元 ANNOTATION(元注解 了解) 499 11.15.1 元注解的基本介绍 499 11.15.2 元注解的种类 (使用不多了解, 不用深入研究) 499 11.15.3 Retention 注解 499 11.15.4 Target 500 11.15.5 Documented 501 11.15.6 Inherited 注解 501 11.16 第 10 章作业 501 第 12 章 异常-EXCEPTION 504 12.1 看个实际的问题和一段代码 504 12.2 解决方案-异常捕获 504 12.3 异常介绍 505 12.4 异常体系图一览 506 12.4.1 异常体系图 506 12.4.2 异常体系图的小结 506 12.5 常见的运行时异常 507 12.5.1 常见的运行时异常包括 507 12.5.2 常见的运行时异常举例 507 12.6 编译异常 511 12.6.1 介绍 512 12.6.2 常见的编译异常 512 12.6.3 案例说明 512 12.7 异常课堂练习 513 12.8 异常处理 513 12.8.1 基本介绍 514 12.8.2 异常处理的方式 514 12.8.3 示意图 514 12.9 TRY-CATCH 异常处理 515 12.9.1 try-catch 方式处理异常说明 TryCatch01.java 515 12.9.2 try-catch 方式处理异常-快速入门 515 12.9.3 try-catch 方式处理异常-注意事项 TryCatchDetail.java 516 12.9.4 异常处理课堂练习 521 12.9.5 try-catch-finally 执行顺序小结 523 12.9.6 课后练习题: TryCatchExercise04.java 523
12.10 THROWS 异常处理 525 12.10.1 基本介绍 525 12.10.2 快速入门案例 525 12.10.3 注意事项和使用细节 ThrowsDetail.java 525 12.11 自定义异常 528 12.11.1 基本概念 528 12.11.2 自定义异常的步骤 528 12.11.3 自定义异常的应用实例 CustomException.java 528 12.12 THROW 和 THROWS 的区别 530 12.12.1 一览表 530 12.12.2 测试题-下面的测试输出什么 ThrowException.java 2min 530 12.13 本章作业 530 第 13 章 常用类 533 13.1 包装类 533 13.1.1 包装类的分类 WrapperType.java 533 13.1.2 包装类和基本数据的转换 533 13.1.3 案例演示 Integer01.java 533 13.1.4 课堂测试题 WrapperExercise01.java 2min 535 13.1.5 包装类型和 String 类型的相互转换 WrapperVSString.java 535 13.1.6 Integer 类和 Character 类的常用方法 536 13.1.7 Integer 类面试题 1 WrapperExercise02.java 537 13.1.8 Intege 类面试题总结 539 13.2 STRING 类 540 13.2.1 String 类的理解和创建对象 540 13.2.2 创建 String 对象的两种方式 542 13.2.3 两种创建 String 对象的区别 542 13.2.4 课堂测试题 StringExercise01.java 543 13.3 字符串的特性 546 13.3.1 说明 StringExercise06.java 546 13.3.2 面试题 547 13.4 STRING 类的常见方法 549 13.4.1 说明 549 13.4.2 String 类的常见方法一览 550 13.5 STRINGBUFFER 类 555 13.5.1 基本介绍 555 13.5.2 String VS StringBuffer 557 13.5.3 String 和 StringBuffer 相互转换 557 13.5.4 StringBuffer 类常见方法 558
13.5.5 StringBuffer 类课堂测试题 1 StringBufferExercise01.java 560 13.5.6 StringBuffer 类课后练习 2 561 13.6 STRINGBUILDER 类 563 13.6.1 基本介绍 563 13.6.2 StringBuilder 常用方法 564 13.6.3 String、StringBuffer 和 StringBuilder 的比较 565 13.6.4 String、StringBuffer 和 StringBuilder 的效率测试 565 13.6.5 String、StringBuffer 和 StringBuilder 的选择 567 13.7 MATH 类 567 13.7.1 基本介绍 568 13.7.2 方法一览(均为静态方法) 568 13.7.3 Math 类常见方法应用案例 568 13.8 ARRAYS 类 570 13.8.1 Arrays 类常见方法应用案例 570 13.8.2 Arrays 类课堂练习 579 13.9 SYSTEM 类 584 13.9.1 System 类常见方法和案例 584 13.10 BIGINTEGER 和 BIGDECIMAL 类 586 13.10.1 BigInteger 和 BigDecimal 介绍 586 13.10.2 BigInteger 和 BigDecimal 常见方法 587 13.11 日期类 589 13.11.1 第一代日期类 590 13.11.2 第二代日期类 592 13.11.3 第三代日期类 593 13.11.4 DateTimeFormatter 格式日期类 596 13.11.5 Instant 时间戳 596 13.11.6 第三代日期类更多方法 598 13.12 本章作业 598 第 14 章 集合 600 14.1 集合的理解和好处 600 14.1.1 数组 600 14.1.2 集合 600 14.2 集合的框架体系 600 14.3 COLLECTION 接口和常用方法 602 14.3.1 Collection 接口实现类的特点 602 14.3.2 Collection 接口遍历元素方式 1-使用 Iterator(迭代器) 604 14.3.3 Collection 接口遍历对象方式 2-for 循环增强 610 14.3.4 课堂练习 610
14.4 LIST 接口和常用方法 613 14.4.1 List 接口基本介绍 613 14.4.2 List 接口的常用方法 615 14.4.3 List 接口课堂练习 617 14.4.4 List 的三种遍历方式 [ArrayList, LinkedList,Vector] 619 14.4.5 实现类的课堂练习 2 621 14.5 ARRAYLIST 底层结构和源码分析 624 14.5.1 ArrayList 的注意事项 624 14.5.2 ArrayList 的底层操作机制源码分析(重点难点.) 624 14.6 VECTOR 底层结构和源码剖析 626 14.6.1 Vector 的基本介绍 626 14.6.2 Vector 和 ArrayList 的比较 629 14.7 LINKEDLIST 底层结构 630 14.7.1 LinkedList 的全面说明 630 14.7.2 LinkedList 的底层操作机制 630 14.7.3 LinkedList 的增删改查案例 634 14.8 ARRAYLIST 和 LINKEDLIST 比较 639 14.8.1 ArrayList 和 LinkedList 的比较 639 14.9 SET 接口和常用方法 639 14.9.1 Set 接口基本介绍 639 14.9.2 Set 接口的常用方法 640 14.9.3 Set 接口的遍历方式 640 14.9.4 Set 接口的常用方法举例 640 14.10 SET 接口实现类-HASHSET 642 14.10.1 HashSet 的全面说明 642 14.10.2 HashSet 案例说明 644 14.10.3 HashSet 底层机制说明 646 14.10.4 HashSet 课堂练习 1 655 14.10.5 HashSet 课后练习 2 658 14.11 SET 接口实现类-LINKEDHASHSET 659 14.11.1 LinkedHashSet 的全面说明 659 14.11.2 LinkedHashSet 课后练习题 LinkedHashSetExercise.java 660 14.12 MAP 接口和常用方法 663 14.12.1 Map 接口实现类的特点 [很实用] 663 14.12.2 Map 接口常用方法 666 14.12.3 Map 接口遍历方法 668 14.12.4 Map 接口课堂练习 672 14.13 MAP 接口实现类-HASHMAP 676 14.13.1 HashMap 小结 676
14.13.2 HashMap 底层机制及源码剖析 676 14.13.3 HashMap 底层机制及源码剖析 677 14.14 MAP 接口实现类-HASHTABLE 683 14.14.1 HashTable 的基本介绍 683 14.14.2 Hashtable 和 HashMap 对比 684 14.15 MAP 接口实现类-PROPERTIES 684 14.15.1 基本介绍 684 14.15.2 基本使用 684 14.16 总结-开发中如何选择集合实现类(记住) 686 14.17 COLLECTIONS 工具类 692 14.17.1 Collections 工具类介绍 692 14.17.2 排序操作 (均为 static 方法) 692 14.17.3 排序操作 (均为 static 方法) 696 14.17.4 查找、替换 696 14.18 本章作业 696 第 15 章 泛型 700 15.1 泛型的理解和好处 700 15.1.1 看一个需求 700 15.1.2 使用传统方法的问题分析 703 15.1.3 泛型快速体验-用泛型来解决前面的问题 703 15.2 泛型的理解和好处 707 15.2.1 泛型的好处 707 15.3 泛型介绍 707 15.4 泛型的语法 711 15.4.1 泛型的声明 711 15.4.2 泛型的实例化 711 15.4.3 泛型使用举例 711 15.4.4 泛型使用的注意事项和细节 GenericDetail.java 715 15.5 泛型课堂类型 719 15.5.1 泛型课堂练习题 719 15.6 自定义泛型 721 15.6.1 自定义泛型类 (难度) 722 15.6.2 自定义泛型接口 727 15.6.3 自定义泛型方法 731 15.6.4 自定义泛型方法 734 15.7 泛型的继承和通配符 735 15.7.1 泛型的继承和通配符说明 GenericExtends.java 735 15.7.2 应用案例 735
15.8 本章作业 739 15.9 JUNIT 739 15.9.1 为什么需要 JUnit 739 15.9.2 基本介绍 740 15.9.3 使用步骤,看老师演示 JUnit_.java 740 第 16 章 坦克大战[1] 742 16.1 坦克大战游戏演示 742 16.1.1 游戏演示 742 16.1.2 文档坦克游戏说明文档.doc 742 16.1.3 为什么写这个项目 742 16.1.4 写项目前的提醒 742 16.1.5 如何讲解这个项目,授课的原则: 743 16.2 JAVA 绘图坐标体系 743 16.2.1 坐标体系-介绍 743 16.2.2 坐标体系-像素 743 16.2.3 介绍-快速入门 744 16.2.4 绘图原理 747 16.2.5 Graphics 类 748 16.2.6 绘出坦克 751 16.2.7 绘图练习 757 16.3 JAVA 事件处理机制 757 16.3.1 事件处理机制-看个问题 757 16.3.2 基本说明 761 16.3.3 请大家看一个示意图 761 16.3.4 机制分析 761 16.3.5 事件处理机制深入理解 761 16.4 坦克大战游戏 762 16.4.1 让你的坦克动起来 762 16.5 本章作业 763 16.5.1 本章作业 763 16.5.2 本章内容小结 774 第 17 章 多线程基础 775 17.1 线程相关概念 775 17.1.1 程序(program) 775 17.1.2 进程 775 17.1.3 什么是线程 775 17.1.4 其他相关概念 776
17.2 线程基本使用 777 17.2.1 创建线程的两种方式 777 17.2.2 线程应用案例 1-继承 Thread 类 777 17.2.3 线程应用案例 2-实现 Runnable 接口 781 17.2.4 线程使用应用案例-多线程执行 785 17.2.5 线程如何理解 788 17.3 继承 THREAD VS 实现 RUNNABLE 的区别 788 17.4 线程终止 792 17.4.1 基本说明 792 17.4.2 应用案例 ThreadExit_.java com.hspedu.exit_ 792 17.5 线程常用方法 793 17.5.1 常用方法第一组 793 17.5.2 注意事项和细节 793 17.5.3 应用案例 ThreadMethod01.java 793 17.5.4 常用方法第二组 793 17.5.5 应用案例 794 17.5.6 课堂练习 794 17.5.7 用户线程和守护线程 796 17.5.8 应用案例 ThreadMethod03.java 796 17.6 线程的生命周期 797 17.6.1 JDK 中用 Thread.State 枚举表示了线程的几种状态 797 17.6.2 线程状态转换图 797 17.6.3 写程序查看线程状态 ThreadState_.java 798 17.7 线程的同步 800 17.7.1 先看一个问题 800 17.8 SYNCHRONIZED 800 17.8.1 线程同步机制 800 17.8.2 同步具体方法-Synchronized 800 17.9 分析同步原理 801 17.10 互斥锁 801 17.10.1 基本介绍 801 17.10.2 使用互斥锁来解决售票问题 802 17.10.3 注意事项和细节 808 17.11 线程的死锁 808 17.11.1 基本介绍 808 17.11.2 应用案例 809 17.11.3 应用案例 DeadLock_.java 809 17.12 释放锁 811 17.12.1 下面操作会释放锁 811
17.12.2 下面操作不会释放锁 811 17.13 本章作业 812 第 18 章 坦克大战【2】 813 18.1 线程-应用到坦克大战 813 18.1.1 坦克大战 0.3 813 18.1.2 坦克大战 0.4 版 813 第 19 章 IO 流 816 19.1 文件 816 19.1.1 什么是文件 816 19.1.2 文件流 816 19.2 常用的文件操作 816 19.2.1 创建文件对象相关构造器和方法 816 19.2.2 获取文件的相关信息 820 19.2.3 应用案例演示 FileInformation.java 820 19.2.4 目录的操作和文件删除 822 19.2.5 应用案例演示 822 19.3 IO 流原理及流的分类 822 19.3.1 Java IO 流原理 822 19.3.2 流的分类 822 19.4 IO 流体系图-常用的类 823 19.4.1 FileInputStream 介绍 824 19.4.2 FileInputStream 应用实例 FileInputStream_.java 824 19.4.3 FileOutputStream 介绍 827 19.4.4 FileOutputStream 应用实例 1 FileOutputStream01.java 828 19.4.5 FileOutputStream 应用实例 2 FileCopy.java 830 19.4.6 FileReader 和 FileWriter 介绍 832 19.4.7 FileReader 相关方法 833 19.4.8 FileWriter 常用方法 833 19.4.9 FileReader 和 FileWriter 应用案例 FileReader_.java 833 19.5 节点流和处理流 839 19.5.1 基本介绍 839 19.5.2 节点流和处理流一览图 840 19.5.3 节点流和处理流的区别和联系 840 19.5.4 处理流的功能主要体现在以下两个方面: 840 19.5.5 处理流-BufferedReader 和 BufferedWriter 841 19.5.6 处理流-BufferedInputStream 和 BufferedOutputStream 846 19.5.7 介绍 BufferedOutputStream 847
19.5.8 对象流-ObjectInputStream 和 ObjectOutputStream 850 19.5.9 对象流介绍 851 19.5.10 标准输入输出流 854 19.5.11 转换流-InputStreamReader 和 OutputStreamWriter 854 19.6 打印流-PRINTSTREAM 和 PRINTWRITER 858 19.7 PROPERTIES 类 861 19.7.1 看一个需求 861 19.7.2 基本介绍 863 19.7.3 应用案例 863 19.8 本章作业 867 第 20 章 坦克大战【3】 868 20.1 IO 流-应用到坦克大战 868 20.1.1 坦克大战 0.5 版 868 20.1.2 坦克大战 0.6 版 869 20.2 第二个阶段就到这里大家好好总结 869 第 21 章 网络编程 871 21.1 网络的相关概念 871 21.1.1 网络通信 871 21.1.2 网络 871 21.1.3 ip 地址 871 21.1.4 ipv4 地址分类 872 21.1.5 域名 873 21.1.6 网络通信协议 873 21.1.7 网络通信协议 874 21.1.8 TCP 和 UDP 874 21.2 INETADDRESS 类 875 21.2.1 相关方法 875 21.2.2 应用案例 com.hspedu.api API_.java 875 21.3 SOCKET 875 21.3.1 基本介绍 876 21.4 TCP 网络通信编程 876 21.4.1 基本介绍 876 21.4.2 应用案例 1(使用字节流) 877 21.4.3 应用案例 2(使用字节流) SocketTCP02.java 880 21.4.4 应用案例 3(使用字符流) 884 21.4.5 应用案例 4 TCPFileUploadServer.java TCPFileUploadClient.java 888 21.4.6 netstat 指令 893
21.4.7 TCP 网络通讯不为人知的秘密 894 21.5 UDP 网络通信编程[了解] 894 21.5.1 基本介绍 895 21.5.2 基本流程 895 21.5.3 应用案例 895 21.6 本章作业 899 第 22 章 多用户即时通信系统 901 22.1 QQ 聊天项目演示 901 22.1.1 项目 QQ 演示 901 22.2 为什么选择这个项目 902 22.2.1 项目开发流程 902 22.2.2 需求分析 903 22.2.3 界面设计 903 22.2.4 功能实现-用户登录 905 22.2.5 功能实现-拉取在线用户列表 907 22.2.6 功能实现-无异常退出 907 22.2.7 功能实现-私聊 907 22.2.8 功能实现-群聊 908 22.2.9 功能说明-发文件 909 22.2.10 功能实现-服务器推送新闻 910 22.2.11 多用户即时通信系统 911 第 23 章 反射(REFLECTION) 913 23.1 一个需求引出反射 913 23.1.1 请看下面的问题 913 23.2 反射机制 915 23.2.1 Java Reflection 915 23.2.2 Java 反射机制原理示意图!!! 916 23.2.3 Java 反射机制可以完成 916 23.2.4 反射相关的主要类 917 23.2.5 反射优点和缺点 919 23.2.6 反射调用优化-关闭访问检查 922 23.3 CLASS 类 923 23.3.1 基本介绍 923 23.3.2 Class 类的常用方法 925 23.3.3 应用实例 Class02.java 926 23.4 获取 CLASS 类对象 928 23.5 哪些类型有 CLASS 对象 931
23.5.1 如下类型有 Class 对象 931 23.5.2 应用实例 AllTypeClass.java 931 23.6 类加载 932 23.6.1 基本说明 932 23.6.2 类加载时机 933 23.6.3 类加载过程图 933 23.6.4 类加载各阶段完成任务 933 23.6.5 加载阶段 934 23.6.6 连接阶段-验证 934 23.6.7 连接阶段-准备 935 23.6.8 连接阶段-解析 936 23.6.9 Initialization(初始化) 936 23.7 通过反射获取类的结构信息 938 23.7.1 第一组: java.lang.Class 类 939 23.7.2 第二组: java.lang.reflect.Field 类 939 23.7.3 第三组: java.lang.reflect.Method 类 939 23.7.4 第四组: java.lang.reflect.Constructor 类 939 23.8 通过反射创建对象 946 23.8.1 案例演示 com.hspedu.reflection ReflecCreateInstance.java 947 23.9 通过反射访问类中的成员 949 23.9.1 访问属性 ReflecAccessProperty.java 950 23.9.2 访问方法 ReflecAccessMethod.java 952 23.10 本章作业 955 第 24 章 零基础学 MYSQL 956 24.1 一个问题 956 24.2 解决之道 956 24.2.1 解决之道-文件、数据库 956 24.2.2 MySQL 数据库的安装和配置(安装演示) 956 24.2.3 使用命令行窗口连接 MYSQL 数据库[示意图] 957 24.2.4 操作示意图 957 24.3 NAVICAT 安装和使用 958 24.3.1 介绍 : 图形化 MySQL 管理软件 958 24.3.2 下载安装使用 958 24.3.3 演示使用 Navicat 创建一个数据库 db01 在 db01 创建一张表 users , 保存 3 个用户 958 24.3.4 老韩扩 我使用命令行完成 958 24.4 SQLYOG[SQLYOG] 安装和使用 958 24.4.1 介绍 : 图形化 MySQL 管理软件 958 24.4.2 下载安装使用 959
24.4.3 演示使用 SQLyog 创建一个数据库 db01 在 db01 创建一张表 users , 保存 3 个用户 959 24.5 数据库三层结构-破除 MYSQL 神秘 959 24.6 数据在数据库中的存储方式 960 24.7 SQL 语句分类 960 24.8 创建数据库 961 24.9 查看、删除数据库 962 24.10 备份恢复数据库 962 24.11 备份恢复数据库的表 963 24.12 安装 ECSHOP 数据库 963 24.13 创建表 (按课程大纲顺序) 964 24.14 MYSQL 常用数据类型(列类型) 965 24.14.1 数值型(整数)的基本使用 965 24.14.2 型如何定义一个无符号的整数 966 24.14.3 数值型(bit)的使用 967 24.14.4 数值型(小数)的基本使用 967 24.14.5 字符串的基本使用 969 24.14.6 字符串使用细节 970 24.14.7 日期类型的基本使用 972 24.15 创建表练习 972 24.16 修改表-基本介绍 974 24.17 修改表-课堂练习 974 24.18 数据库 C[CREATE]R[READ]U[UPDATE]D[DELETE]语句 976 24.19 INSERT 语句 976 24.19.1 使用 INSERT 语句向表中插入数据。insert.sql 976 24.19.2 学员练习使用 insert 语句向表 employee 中插入 2 个员工的信息。 977 24.19.3 细节说明 insertdetail.sql 977 24.20 UPDATE 语句 979 24.20.1 使用 update 语句修改表中数据 979 24.20.2 基本使用 update.sql 979 24.20.3 使用细节: 980 24.21 DELETE 语句 980 24.21.1 使用 delete 语句删除表中数据 980 24.21.2 使用细节 981 24.22 SELECT 语句 981 24.22.1 基本语法 981 24.22.2 注意事项 (创建测试表学生表 ) 981 24.22.3 课堂练习: select01.sql 982 24.22.4 使用表达式对查询的列进行运算 983 24.22.5 在 select 语句中可使用 as 语句 983
24.22.6 练习 select02.sql 983 24.22.7 在 where 子句中经常使用的运算符 983 24.22.8 使用 where 子句进行过滤查询 select03.sql 984 24.22.9 课堂练习 986 24.22.10 使用 order by 子句排序查询结果 986 24.23 合计/统计函数 987 24.23.1 count 987 24.23.2 sum 989 24.23.3 avg 990 24.23.4 max/min 991 24.23.5 使用 group by 子句对列进行分组 [先创建测试表] 992 24.23.6 使用 having 子句对分组后的结果进行过滤 992 24.24 字符串相关函数 996 24.25 数学相关函数 998 24.26 时间日期相关函数 DATE.SQL 1000 24.27 加密和系统函数 PWD.SQL 1006 24.28 流程控制函数 1007 24.29 MYSQL 表查询 加强… 1010 24.29.1 介绍 1010 24.29.2 分页查询 1011 24.29.3 使用分组函数和分组子句 group by 1013 24.29.4 数据分组的总结 1015 24.30 MYSQL 多表查询 1015 24.30.1 问题的引出(重点难点) 1015 24.30.2 说明 1016 24.30.3 多表查询练习 many_tab.sql 1016 24.30.4 自连接 1017 24.31 MYSQL 表子查询 1018 24.31.1 什么是子查询 subquery.sql 1018 24.31.2 单行子查询 1018 24.31.3 请思考如何显示与 SMITH 同一部门的所有员工? 1018 24.31.4 多行子查询 1019 24.31.5 子查询当做临时表使用 练习题 subquery.sql 1020 24.31.6 在多行子查询中使用 all 操作符 1021 24.31.7 在多行子查询中使用 any 操作符 1023 24.31.8 多列子查询 manycolumn.sql 1024 24.31.9 在 from 子句中使用子查询 subquery03.sql 1026 24.31.10 在 from 子句中使用子查询—课堂小练习 1026 24.32 表复制 1028
24.32.1 自我复制数据(蠕虫复制) 1028 24.33 合并查询 1031 24.33.1 介绍 1031 24.34 MYSQL 表外连接 1032 24.34.1 提出一个问题 1032 24.34.2 外连接 1032 24.34.3 课堂练习 1036 24.35 MYSQL 约束 1036 24.35.1 基本介绍 1037 24.35.2 primary key(主键)-基本使用 1037 24.35.3 not null(非空) 1040 24.35.4 unique(唯一) 1040 24.35.5 foreign key(外键) 1041 24.35.6 check 1044 24.35.7 商店售货系统表设计案例[先练,再评 10min] 1045 24.36 自增长 1047 24.36.1 自增长基本介绍 一个问题 1047 24.36.2 自增长使用细节 1048 24.37 MYSQL 索引 1051 24.37.1 索引快速入门 1051 24.37.2 索引的原理 1056 24.37.3 索引的类型 1056 24.37.4 索引使用 1056 24.37.5 索引课堂练习 1059 24.37.6 小结: 哪些列上适合使用索引 1059 24.38 MYSQL 事务 1060 24.38.1 什么是事务 1060 24.38.2 事务和锁 1060 24.38.3 回退事务 1062 24.38.4 提交事务 1062 24.38.5 事务细节讨论 transaction_detail.sql 1062 24.39 MYSQL 事务隔离级别 1063 24.39.1 事务隔离级别介绍 1063 24.39.2 查看事务隔离级别 1064 24.39.3 事务隔离级别 1064 24.39.4 mysql 的事务隔离级 案例… 1065 24.39.5 设置事务隔离级别 1065 24.40 MYSQL 事务 ACID 1067 24.40.1 事务的 acid 特性 1067
24.40.2 事务的课堂练习 [一定要自己去练习体会] 1067 24.41 MYSQL 表类型和存储引擎 1067 24.41.1 基本介绍 1068 24.41.2 主要的存储引擎/表类型特点 1068 24.41.3 细节说明 1068 24.41.4 三种存储引擎表使用案例 1069 24.41.5 如何选择表的存储引擎 1070 24.41.6 修改存储引擎 1070 24.42 视图(VIEW) 1071 24.42.1 看一个需求 1071 24.42.2 基本概念 1071 24.42.3 视图的基本使用 1072 24.42.4 完成前面提出的需求 view.sql 1072 24.42.5 视图细节讨论 1074 24.42.6 视图最佳实践 1075 24.42.7 视图课堂练习(学员练习) 1075 24.43 MYSQL 管理 1076 24.43.1 Mysql 用户 1076 24.43.2 创建用户 1077 24.43.3 删除用户 1077 24.43.4 用户修改密码 1077 24.43.5 mysql 中的权限 1077 24.43.6 给用户授权 1078 24.43.7 回收用户授权 1079 24.43.8 权限生效指令 1079 24.43.9 课堂练习题 grant.sql 1079 24.43.10 细节说明 manage_detail.sql 1081 24.44 本章作业 1082
第 1 章 内容介绍 1 本套 Java 课程内容 1课程的三个阶段 1.2关于课程的说明 关于这套课程老韩要给小伙伴们说 以培养编程思想、提升编程能力为核心目标达到能分析业务需求并能用代码实现水平 抛弃传统的以强灌知识点授课方式每个阶段都有多个项目把知识点真正应用到项目中, 小伙伴在学习过程中有满 满成就感充分体会编程乐趣 课程成完整体系超全超详细。 充分考虑零基础小伙伴通俗易懂 宁肯慢点也不遗漏细节。[包括软件安装、开发环境配置和使用] 项目是从小到大的过程项目分解成不同的功能模块随功能的增加,将知识点融入到项目整个过程是循序渐进的。 让大家轻松的学高效的学。 为减轻小伙伴学习压力将课程分为三个阶段小伙伴可以根据当前水平选择从某个阶段开始学习 零基础的小伙伴老韩强烈建议从第一阶段开始学习. 因为课程内容非常全录制周期长老韩也会根据实际情况做微调
1.3课程特色
1.2 Java 就业方向
1.3 Java 开发场景举例 1-SSM
1.4 Java 开发场景举例 2Android 核心代码
1.5 Java 开发场景举例 3 大数据-hadoop
1.6 Java 的应用领域 1.6. 1企业级应用 主要指复杂的大企业的软件系统、各种类型的网站。应用领域包括金融、电信、交通、电子商务等。
1.6.2Android 平台应用 Android 应用程序使用 Java 语言编写。Android 开发水平的高低很大程度上取决于 Java语言核心能力是否扎实。
1.6.3移动领域应用 主要表现在消费和嵌入式领域是指在各种小型设备上的应用包括机顶盒、车载的大屏影音娱乐设备、汽车通信 设备、扫码的 POS 机等。
第 2 章 Java 概述 2. 1 什么是程序 程序计算机执行某些操作或解决某个问题而编写的一系列有序指令的集合 举例说明:
2.2 Java 诞生小故事
2.3 Java 技术体系平台
2.4 Java 重要特点 Java 语言是面向对象的(oop) Java 语言是健壮的。Java 的强类型机制、异常处理、垃圾的自动收集等是 Java程序健壮性的重要保证 Java 语言是跨平台性的。[即: 一个编译好的.class 文件可以在多个系统下运行这种特性称为跨平台] Java 语言是解释型的[了解] 解释性语言javascript,PHP, java 编译性语言: c / c 区别是解释性语言编译后的代码不能直接被机器执行,需要解释器来执行, 编译性语言, 编译后的代码, 可 以直接被机器执行, c /c 2.5 Java 的开发工具
2.5. 1工具选择 如何选择开发工具 我们先选择用文本编辑器本 sublime 到大家对java 有一定了解后我们再使用 IDEA 和 Eclipse 开发工具。 这是为什么呢 更深刻的理解java 技术,培养代码感。【面试时往往程序员手写代码】 有利于公司面试。 2.6 Java 运行机制及运行过程 2.6. 1Java 语言的特点跨平台性
2.6.2Java 核心机制-Java 虚拟机 [JVMjava virtual machine] 基本介绍
JVM 是一个虚拟的计算机具有指令集并使用不同的存储区域。负责执行指令管理数据、内存、寄存器包含在 JDK 中.对于不同的平台有不同的虚拟机。Java 虚拟机机制屏蔽了底层运行平台的差别实现了“一次编译到处运行” [说明] 示意图
2.7 什么是 JDK JRE 2.7. 1JDK 基本介绍
JDK 的全称(Java Development Kit Java 开发工具包) JDK JRE java 的开发工具 [java, javac,javadoc,javap 等]JDK 是提供给 Java 开发人员使用的其中包含了java 的开发工具也包括了 JRE 。所以安装了 JDK 就不用在单独 安装 JRE 了。 2.7.2JRE 基本介绍JRE(Java Runtime Environment Java 运行环境) JRE JVM Java 的核心类库[类]包括 Java 虚拟机(JVM Java Virtual Machine)和 Java 程序所需的核心类库等如果想要运行一个开发好的 Java 程序 计算机中只需要安装 JRE 即可。 2.7.3JDK 、JRE 和 JVM 的包含关系JDK JRE 开发工具集 (例如 Javac,java 编译工具等)JRE JVM Java SE 标准类库 (java 核心类库)如果只想运行开发好的 .class 文件 只需要 JRE 2.8 下载、安装 JDK
2.9 配置环境变量 path 2.9. 1为什么要配置 path
2.9.2配置环境变量 path 的步骤 10 安装 JDK 的练习 1 请同学们安装好 JDK 配置好 path 环境变量。可以在控制台下正确的执行, ( 10min) 10.2 环境变量配置细节说明: 11 Java 快速入门 1 需求说明 要求开发一个 Hello.java 程序可以输出 “hello,world!” 11.2 开发步骤
将 Java 代码编写到扩展名为 Hello.java 的文件中。[代码说明]通过 javac 命令对该 java 文件进行编译生成 .class 文件。通过 java 命令对生成的 class 文件进行运行。 11.3 运行原理示意图 12 Java 开发快速入门
//这是java 的快速入门 演示java 的开发步骤 //对代码的相关说明 //1. public class Hello 表示 Hello 是一个类,是一个 public 公有的类 //2. Hello { } 表示一个类的开始和结束 //3. public static void main(String[] args) 表示一个主方法, 即我们程序的入口
//4. main() {} 表示方法的开始和结束 //5. System.out.println(“hello,world~”); 表示输出hello,world~到屏幕 //6. ;表示语句结束 public class Hello {
//编写一个 main 方法 public static void main(String[] args) { System.out.println(“韩顺平教育 hello”); }
}
//一个源文件中最多只能有一个 public 类。其它类的个数不限。[演示] //Dog 是一个类 //编译后每一个类都对于一个.class class Dog {
//一个源文件中最多只能有一个 public 类。其它类的个数不限也可以将 main 方法写在非 public 类中 //然后指定运行非 public 类这样入口方法就是非 public 的 main 方法 public static void main(String[] args) { System.out.println(“hello, 小狗狗~”); } }
class Tiger {
public static void main(String[] args) { System.out.println(“hello, 小老虎~”); }
} 13 Java 开发注意事项和细节说明 14 老韩聊: 如何快速掌握技术或知识点 15 Java 转义字符 1 Java 常用的转义字符 在控制台输入 tab 键可以实现命令补全 \t 一个制表位实现对齐的功能 \n 换行符 \ 一个 :一个 ’ 一个’ \r :一个回车 System.out.println(“韩顺平教育\r 北京”); 15.2 说明 应用实例
//演示转义字符的使用 public class ChangeChar {
//编写一个 main 方法 public static void main(String[] args) {
//\t 一个制表位实现对齐的功能 System.out.println(“北京\t 天津\t 上海”); // \n 换行符 System.out.println(“jack\nsmith\nmary”); // \ 一个\ \ System.out.println(“C:\Windows\System32\cmd.exe”); // :一个 System.out.println(“老韩说:“要好好学习java,有前途””); // ’ 一个’ System.out.println(“老韩说:‘要好好学习java,有前途’”);
// \r :一个回车 System.out.println(“韩顺平教育\r 北京”); // 解读 // 1. 输出 韩顺平教育 // 2. \r 表示回车 System.out.println(“韩顺平教育\r 北京”); // 北京平教育 }
}
15.3 课堂练习 要求请使用一句输出语句达到输入如下图形的效果 2min
public class ChangeCharExer01 {
//编写一个 main 方法 public static void main(String[] args) { //完成代码 System.out.println(“书名\t 作者\t 价格\t 销量\n 三国\t 罗贯中\t120\t1000”);
//示意 可读性很好 //下面代码完成 两个数相加 //定义变量 int n1 10; int n2 30; //求和 int sum n1 n2; //输出结果 System.out.println(“结果” sum); } } 2. 16 初学java 易犯错误
17 注释(comment) 1 介绍
用于注解说明解释程序的文字就是注释注释提高了代码的阅读性 (可读性) 注释是一个程序员必须要具有的良 好编程习惯。将自己的思想通过注释先整理出来再用代码去体现。 [举例]
17.2 Java 中的注释类型
单行注释 //多行注释 /* */文档注释 /** */ 17.3 单行注释 基本格式 格式 //注释文字 17.4 多行注释 基本格式 格式 /* 注释文字 */ 17.5 使用细节
被注释的文字不会被 JVM (java 虚拟机) 解释执行多行注释里面不允许有多行注释嵌套 17.6 文档注释 17.7 代码演示
//演示注释使用
public class Comment01 {
//编写一个 main 方法 public static void main(String[] args) { //单行注释
//多行注释 /* 示意 可读性很好 下面代码完成 两个数相加 定义变量
注释 注释 int n1 10;… System.out.println(“ok~~”); */ int n1 10; int n2 30; //求和 int sum n1 n2; //输出结果 System.out.println(“结果” sum); } }
/**
author 韩顺平version 1.0 */ public class Comment02 {
//编写一个 main 方法 public static void main(String[] args) { //选中然后输入 tab 整体右移 //选中然后输入 shifttab 整体左移 int n1 1 2; int n2 5 10;
int n2 1 3 * 34; } } 18 Java 代码规范 19 DOS 命令(了解) 1 DOS 介绍 Dos Disk Operating System 磁盘操作系统, 简单说一下 windows 的目录结构。[原理图] 19.2 相关的知识补充: 相对路径 绝对路径 19.3 常用的 dos 命令
查看当前目录是有什么内容 dir dir dir d:\abc2\test200切换到其他盘下盘符号 cd : change directory 案例演示切换到 c 盘 cd /D c:切换到当前盘的其他目录下 (使用相对路径和绝对路径演示), …\表示上一级目录 案例演示 cd d:\abc2\test200 cd …\abc2\test200切换到上一级 案例演示 cd …切换到根目录cd \ 案例演示cd \查看指定的目录下所有的子级目录 tree清屏 cls [苍老师]退出 DOS exit说明: 因为小伙伴后面使用 DOS 非常少所以对下面的几个指令老韩给大家演示下, 大家了解即可 (md[创建目 录],rd[删除目录],copy[拷贝文件],del[删除文件],echo[输入内容到文件],type,move[剪切]) Linux, 2.20 本章作业
第 3 章 变量 3. 1 为什么需要变量 3. 1. 1 一个程序就是一个世界 1.2变量是程序的基本组成单位 1.3简单的原理示意图
3.2 变(变化)量(值)的介绍 3.2. 1概念
变量相当于内存中一个数据存储空间的表示你可以把变量看做是一个房间的门牌号通过门牌号我们可以找到房 间而通过变量名可以访问到变量(值)。
3.2.2变量使用的基本步骤
声明变量 int a;赋值 a 60; //应该这么说: 把 60 赋给 a 使用 System.out.println(a);
//也可以一步到位[int a 60; 通常我们是一步完成] 3.3 变量快速入门 变量使用入门案例 看演示并对代码进行说明 演示记录 人的信息的代码
public class Var02 {
//编写一个 main 方法 public static void main(String[] args) { //记录人的信息 int age 30; double score 88.9; char gender ‘男’; String name “king”; //输出信息, 快捷键 System.out.println(“人的信息如下:”); System.out.println(name); System.out.println(age); System.out.println(score); System.out.println(gender);
} }
3.4 变量使用注意事项
public class VarDetail {
//编写一个 main 方法 public static void main(String[] args) { //变量必须先声明后使用, 即有顺序 int a 50;//int System.out.println(a);//50 //该区域的数据/值可以在同一类型范围内不断变化 //a “jack”; //× a 88; //对 System.out.println(a);//88
//变量在同一个作用域内不能重名 //int a 77;//错误
} }
class Dog { public static void main(String[] args) { int a 666;//对 } } 3.5 程序中 号的使用
3.6 数据类型 每一种数据都定义了明确的数据类型在内存中分配了不同大小的内存空间(字节)。
上图说明 [老韩要求小伙伴背下来!!!]
java 数据类型分为两大类 基本数据类型 引用类型基本数据类型有 8 中 数值型 [byte , short , int , long , float ,double] char , boolean引用类型 [类接口 数组] 3.7 整数类型 3.7. 1基本介绍 Java 的整数类型就是用于存放整数值的比如 12 , 30, 3456 等等 3.7.2案例演示 byte n1 10; short n2 10; int n3 10;//4 个字节 long n4 10; //8 个字节 3.7.3整型的类型
3.7.4整型的使用细节 IntDetail.java
public class IntDetail {
//编写一个 main 方法 public static void main(String[] args) {
//Java 的整型常量 (具体值) 默认为 int 型声明 long 型常量须后加‘l’或‘L’ int n1 1;//4 个字节 //int n2 1L;//对不对?不对 long n3 1L;//对
} }
3.8 浮点类型 3.8. 1基本介绍 Java 的浮点类型可以表示一个小数比如 123.4 7.8 0. 12 等等 3.8.2案例演示 3.8.3浮点型的分类
3.8.4说明一下
关于浮点数在机器中存放形式的简单说明,浮点数符号位指数位尾数位尾数部分可能丢失造成精度损失(小数都是近似值)。 3.8.5浮点型使用细节 FloatDetail.java
public class FloatDetail {
//编写一个 main 方法 public static void main(String[] args) {
//Java 的浮点型常量(具体值)默认为 double 型声明 float 型常量须后加‘f’或‘F’ //float num1 1. 1; //对不对?错误 float num2 1. 1F; //对的 double num3 1. 1; //对 double num4 1. 1f; //对
//十进制数形式如5. 12 512.0f .512 (必须有小数点) double num5 . 123; //等价 0. 123 System.out.println(num5);
//科学计数法形式:如5. 12e2 [5. 12 * 10 的 2 次方 ] 5. 12E-2 [] System.out.println(5. 12e2);//512.0 System.out.println(5. 12E-2);//0.0512
//通常情况下应该使用 double 型因为它比 float 型更精确。 //[举例说明]double num9 2. 1234567851;float num10 2. 1234567851F; double num9 2. 1234567851; float num10 2. 1234567851F; System.out.println(num9); System.out.println(num10);
//浮点数使用陷阱: 2.7 和 8. 1 / 3 比较 //看看一段代码 double num11 2.7; double num12 2.7; //8. 1 / 3; //2.7 System.out.println(num11);//2.7 System.out.println(num12);//接近 2.7 的一个小数而不是 2.7 //得到一个重要的使用点: 当我们对运算结果是小数的进行相等判断是要小心 //应该是以两个数的差值的绝对值在某个精度范围类判断 if( num11 num12) { System.out.println(“num11 num12 相等”); } //正确的写法 , ctrl / 注释快捷键, 再次输入就取消注释 if(Math.abs(num11 - num12) 0.000001 ) { System.out.println(“差值非常小到我的规定精度认为相等…”);
} // 可以通过java API 来看 下一个视频介绍如何使用 API System.out.println(Math.abs(num11 - num12)); //细节:如果是直接查询得的的小数或者直接赋值是可以判断相等
} }
3.9 Java API 文档
10 字符类型(char) 1 基本介绍 字符类型可以表示单个字符,字符类型是 char char 是两个字节(可以存放汉字) 多个字符我们用字符串 String(我们 后面详细讲解 String) 10.2 案例演示 Char01.java #代码 char c1 ‘a’; char c2 ‘\t’; char c3 ‘韩’; char c4 97;10.3 字符类型使用细节
public class CharDetail {
//编写一个 main 方法 public static void main(String[] args) {
//在java 中char 的本质是一个整数在默认输出时是 unicode 码对应的字符 //要输出对应的数字可以(int)字符 char c1 97; System.out.println(c1); // a
char c2 ‘a’; //输出’a’ 对应的 数字 System.out.println((int)c2); char c3 ‘韩’;
System.out.println((int)c3);//38889 char c4 38889; System.out.println(c4);//韩
//char 类型是可以进行运算的相当于一个整数因为它都对应有 Unicode 码. System.out.println(‘a’ 10);//107
//课堂小测试 char c5 ‘b’ 1;//98 1 99 System.out.println((int)c5); //99 System.out.println(c5); //99-对应的字符-编码表 ASCII(规定好的)c } } 11 ASCII 码介绍(了解) 12 Unicode 编码介绍(了解) 13 UTF-8 编码介绍(了解) 14 布尔类型boolean
public class Boolean01 { //编写一个 main 方法 public static void main(String[] args) { //演示判断成绩是否通过的案例 //定义一个布尔变量 boolean isPass true;// if(isPass true) { System.out.println(“考试通过恭喜”); } else { System.out.println(“考试没有通过下次努力”); } } } 15 基本数据类型转换 1 自动类型转换 15.2 自动类型转换注意和细节
//自动类型转换细节 public class AutoConvertDetail {
//编写一个 main 方法 public static void main(String[] args) { //细节 1 有多种类型的数据混合运算时 //系统首先自动将所有数据转换成容量最大的那种数据类型然后再进行计算 int n1 10; //ok //float d 1 n1 1. 1;//错误 n1 1. 1 结果类型是 double //double d 1 n1 1. 1;//对 n1 1. 1 结果类型是 double float d 1 n1 1. 1F;//对 n1 1. 1 结果类型是 float
//细节 2: 当我们把精度(容量)大 的数据类型赋值给精度(容量)小 的数据类型时 //就会报错反之就会进行自动类型转换。 // //int n2 1. 1;//错误 double - int
//细节 3: (byte, short) 和 char 之间不会相互自动转换 //当把具体数赋给 byte 时( 1)先判断该数是否在 byte 范围内如果是就可以 byte b 1 10; //对 , - 128- 127 // int n2 1; //n2 是 int // byte b2 n2;//错误原因 如果是变量赋值判断类型 // // char c1 b1; //错误 原因 byte 不能自动转成 char // //
//细节 4:byte short char 他们三者可以计算在计算时首先转换为 int 类型
byte b2 1; byte b3 2; short s1 1; //short s2 b2 s1;//错, b2 s1 int int s2 b2 s1;//对, b2 s1 int
//byte b4 b2 b3; //错误: b2 b3 int //
//boolean 不参与转换 boolean pass true; //int num100 pass;// boolean 不参与类型的自动转换
//自动提升原则 表达式结果的类型自动提升为 操作数中最大的类型 //看一道题
byte b4 1; short s3 100; int num200 1; float num300 1. 1F;
double num500 b4 s3 num200 num300; //float - double }
} 15.3 强制类型转换 介绍 自动类型转换的逆过程将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转换符 ( )但可能造成 精度降低或溢出,格外要注意。 案例演示 ForceConvert.java 15.4 强制类型转换细节说明
public class ForceConvertDetail {
//编写一个 main 方法 public static void main(String[] args) {
//演示强制类型转换 //强转符号只针对于最近的操作数有效往往会使用小括号提升优先级 //int x (int)103.561.5;//编译错误 double - int int x (int)(103.561.5);// (int)44.0 - 44 System.out.println(x);//44
char c1 100; //ok int m 100; //ok //char c2 m; //错误 char c3 (char)m; //ok System.out.println(c3);//100 对应的字符, d 字符
} } 3. 16 基本数据类型转换-练习题
17 基本数据类型和 String 类型的转换 1 介绍和使用
public class StringToBasic {
//编写一个 main 方法 public static void main(String[] args) {
//基本数据类型-String
int n1 100; float f1 1. 1F; double d 1 4.5; boolean b 1 true; String s1 n1 “”; String s2 f1 “”; String s3 d 1 “”; String s4 b1 “”; System.out.println(s1 s2 s3 s4);
//String-对应的基本数据类型 String s5 “123”; //会在 OOP 讲对象和方法的时候回详细 //解读 使用 基本数据类型对应的包装类的相应方法得到基本数据类型 int num1 Integer.parseInt(s5); double num2 Double.parseDouble(s5); float num3 Float.parseFloat(s5); long num4 Long.parseLong(s5);
byte num5 Byte.parseByte(s5); boolean b Boolean.parseBoolean(“true”); short num6 Short.parseShort(s5);
System.out.println(“”); System.out.println(num1);//123 System.out.println(num2);//123.0 System.out.println(num3);//123.0 System.out.println(num4);//123 System.out.println(num5);//123 System.out.println(num6);//123 System.out.println(b);//true
//怎么把字符串转成字符 char - 含义是指 把字符串的第一个字符得到 //解读 s5.charAt(0) 得到 s5 字符串的第一个字符 ‘1’ System.out.println(s5.charAt(0));
} }
17.2 注意事项
案例演示: StringToBasicDetail.java
在将 String 类型转成 基本数据类型时 个整数但是不能把 “hello” 转成一个整数
比如 我们可以把 “123” , 转成一
如果格式不正确就会抛出异常程序就会终止 这个问题在异常处理章节中会处理
/**
演示字符串转基本数据类型的细节 */ public class StringToBasicDetail {
//编写一个 main 方法 public static void main(String[] args) {
String str “hello”; //转成 int int n1 Integer.parseInt(str); System.out.println(n1); } }
18 本章作业
第 4 章 运算符 4. 1 运算符介绍 4. 1. 1运算符介绍 运算符是一种特殊的符号用以表示数据的运算、赋值和比较等。
算术运算符赋值运算符关系运算符 [比较运算符]逻辑运算符位运算符 [需要二进制基础]三元运算符 4.2 算术运算符 4.2. 1介绍 算术运算符是对数值类型的变量进行运算的在 Java程序中使用的非常多。 4.2.2算术运算符一览
4.2.3案例演示
/**
演示算术运算符的使用 */ public class ArithmeticOperator {
//编写一个 main 方法 public static void main(String[] args) { // /使用 System.out.println( 10 / 4); //从数学来看是 2.5, java 中 2 System.out.println( 10.0 / 4); //java 是 2.5 // 注释快捷键 ctrl /, 再次输入 ctrl / 取消注释 double d 10 / 4;//java 中 10 / 4 2, 22.0 System.out.println(d);// 是 2.0
// % 取模 ,取余 // 在 % 的本质 看一个公式!!! 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
//的使用 // int i 10; i;//自增 等价于 i i 1; i 11 i;//自增 等价于 i i 1; i 12 System.out.println(“i” i);//12
/* 作为表达式使用 前i 先自增后赋值 后i先赋值后自增 */ int j 8; //int k j; //等价 jj1;kj; int k j; // 等价 k j;jj1; System.out.println(“k” k “j” j);//8 9 } } 4.2.4细节说明
4.2.5面试题
4.2.6自增自减课堂练习, 看看输出什么
//练习
public class ArithmeticOperatorExercise01 {
//编写一个 main 方法 public static void main(String[] args) {
// int i 1;//i- 1 // i i; //规则使用临时变量: ( 1) tempi;(2) ii1;(3)itemp; // System.out.println(i); // 1
// int i1; // ii; //规则使用临时变量: ( 1) ii1;(2) tempi;(3)itemp; // System.out.println(i); //2 // // 测试输出 int i1 10; int i2 20; int i i1; System.out.print(“i”i);//10 System.out.println(“i2”i2);//20 i --i2; System.out.print(“i”i);//19 System.out.println(“i2”i2);//19
} }
4.2.7课堂练习 2
//ArithmeticOperatorExercise02.java
假如还有 59 天放假问合 xx 个星期零 xx 天定义一个变量保存华氏温度华氏温度转换摄氏温度的公式为5/9*(华氏温度- 100),请求出华氏温度对应的摄氏温度。 [234.5]代码
//课堂练习
public class ArithmeticOperatorExercise02 {
//编写一个 main 方法 public static void main(String[] args) {
//1.需求: //假如还有 59 天放假问合 xx 个星期零 xx 天 //2.思路分析 //(1) 使用 int 变量 days 保存 天数 //(2) 一个星期是 7 天 星期数 weeks days / 7 零 xx 天 leftDays days % 7 //(3) 输出
//3.走代码 int days 25911; int weeks days / 7; int leftDays days % 7; System.out.println(days “天 合” weeks “星期零”
leftDays “天”); //1.需求
//定义一个变量保存华氏温度华氏温度转换摄氏温度的公式为 //5/9*(华氏温度- 100),请求出华氏温度对应的摄氏温度 // //2 思路分析 //(1) 先定义一个 double huaShi 变量保存 华氏温度 //(2) 根据给出的公式进行计算即可 5/9*(华氏温度- 100) // 考虑数学公式和java 语言的特性 //(3) 将得到的结果保存到 double sheShi //3 走代码 double huaShi 1234.6; double sheShi 5.0 / 9 * (huaShi - 100); System.out.println(“华氏温度” huaShi 对应的摄氏温度 sheShi);
} }
4.3 关系运算符(比较运算符) 4.3. 1介绍
关系运算符的结果都是 boolean 型也就是要么是true 要么是 false关系表达式 经常用在 if 结构的条件中或循环结构的条件中 4.3.2关系运算符一览
4.3.3案例演示 案例演示关系运算符的使用(RelationalOperator.java)。
//演示关系运算符的使用 //
public class RelationalOperator {
//编写一个 main 方法 public static void main(String[] args) {
int a 9; //老韩提示: 开发中不可以使用 a, b int b 8; System.out.println(a b); //T System.out.println(a b); //T System.out.println(a b); //F System.out.println(a b);//F
System.out.println(a b); //F System.out.println(a ! b); //T boolean flag a b; //T System.out.println(“flag” flag); } }
4.3.4细节说明
关系运算符的结果都是 boolean 型也就是要么是 true 要么是 false。关系运算符组成的表达式我们称为关系表达式。 a b比较运算符“不能误写成” 4.4 逻辑运算符 4.4. 1介绍 用于连接多个条件 (多个关系表达式) 最终的结果也是一个 boolean 值。 4.4.2逻辑运算符一览 分为两组学习短路与 短路或 || 取反 !逻辑与 逻辑或 | ^ 逻辑异或
说明逻辑运算规则 ab : 叫逻辑与规则当 a 和 b 同时为 true ,则结果为 true, 否则为 false ab : 叫短路与规则当 a 和 b 同时为 true ,则结果为 true,否则为 false a|b : | 叫逻辑或规则当 a 和 b 有一个为 true ,则结果为 true,否则为 false a||b : || 叫短路或规则当 a 和 b 有一个为 true ,则结果为 true,否则为 false !a : 叫取反或者非运算。当 a 为 true, 则结果为 false, 当 a 为 false 是结果为 true a^b: 叫逻辑异或当 a 和 b 不同时则结果为 true, 否则为 false 4.4.3 和 基本规则 名称 语法 特点 短路与 条件 1条件 2 两个条件都为true 结果为 true,否则 false 逻辑与 条件 1条件 2 两个条件都为true 结果为 true,否则 false 4.4.4 和 案例演示 案例演示 和 运算符的使用(LogicOperator01.java)。
/**
演示逻辑运算符的使用 */
public class LogicOperator01 {
//编写一个 main 方法 public static void main(String[] args) { //短路与 和 案例演示 int age 50; if(age 20 age 90) {
System.out.println(“ok 100”); }
//逻辑与使用 if(age 20 age 90) { System.out.println(“ok200”); }
//区别 int a 4; int b 9; //对于短路与而言如果第一个条件为 false ,后面的条件不再判断 //对于逻辑与而言如果第一个条件为 false ,后面的条件仍然会判断 if(a 1 b 50) { System.out.println(“ok300”); } System.out.println(“a” a b b);// 4 10
} }
4.4.5 和 使用区别 短路与如果第一个条件为 false 则第二个条件不会判断最终结果为 false 效率高 逻辑与不管第一个条件是否为false 第二个条件都要判断效率低 开发中 我们使用的基本是使用短路与, 效率高 4.4.6 || 和 | 基本规则 名称 语法 特点 短路或|| 条件 1||条件 2 两个条件中只要有一个成立结果为 true,否则为 false |逻辑或 条件 1|条件 2 只要有一个条件成立结果为 true,否则为 false 4.4.7 || 和 | 案例演示
案例演示 || !运算符的使用( i t j )
//演示| || 使用
public class LogicOperator02 {
//编写一个 main 方法 public static void main(String[] args) {
//||短路或 和 |逻辑或 案例演示 //|| 规则: 两个条件中只要有一个成立结果为 true,否则为 false //| 规则: 两个条件中只要有一个成立结果为 true,否则为 false int age 50; if(age 20 || age 30) { System.out.println(“ok 100”); }
//逻辑与使用 if(age 20 | age 30) {
System.out.println(“ok200”); }
//看看区别 //(1)||短路或如果第一个条件为 true //则第二个条件不会判断最终结果为true 效率高 //(2)| 逻辑或不管第一个条件是否为true 第二个条件都要判断效率低 int a 4; int b 9; if( a 1 || b 4) { // 可以换成 | 测试 System.out.println(“ok300”); } System.out.println(“a” a b b); //4 10
} }
4.4.8 || 和 | 使用区别
||短路或如果第一个条件为true 则第二个条件不会判断最终结果为true 效率高| 逻辑或不管第一个条件是否为true 第二个条件都要判断效率低开发中我们基本使用 || 4.4.9 ! 取反 基本规则 名称 语法 特点
! 非 (取反) !条件 如果条件本身成立结果为 false 否则为true
4.4. 10 ! 案例演示 案例演示 !运算符的使用(InverseOperator.java)。
//!和^案例演示
public class InverseOperator {
//编写一个 main 方法 public static void main(String[] args) {
//! 操作是取反 T-F , F - T System.out.println(60 20); //T System.out.println(!(60 20)); //F
//a^b: 叫逻辑异或当 a 和 b 不同时则结果为 true, 否则为 false boolean b (10 1) ^ ( 3 5); System.out.println(“b” b);//T } }
4.4. 11 ^ 案例演示 a^b: 叫逻辑异或当 a 和 b 不同时则结果为 true, 否则为 false ^逻辑异或System.out.println( (4 1) ^ (6 3) ); // ?
4.4. 12 练习题 1 请写出每题的输出结果
4.4. 13 练习题 2 请写输出结果
4.5 赋值运算符 4.5. 1介绍
赋值运算符就是将某个运算后的值赋给指定的变量。
4.5.2赋值运算符的分类
基本赋值运算符 int a 10; 复合赋值运算符 - * / % 等 , 重点讲解一个 其它的使用是一个道理 a b; [等价 a a b; ] a - b; [等价 a a - b; ] 4.5.3案例演示
案例演示赋值运算符的基本使用。AssignOperator.java
赋值基本案例 [int num1 10] 的使用案例
4.5.4赋值运算符特点
运算顺序从右往左 int num a b c;赋值运算符的左边 只能是变量,右边 可以是变量、表达式、常量值 int num 20; int num2 78 * 34 - 10; int num3 a;复合赋值运算符等价于下面的效果 比如a3;等价于 aa3; 其他类推复合赋值运算符会进行类型转换。 byte b 2; b3; b;
//演示赋值运算符的使用
public class AssignOperator {
//编写一个 main 方法 public static void main(String[] args) {
int n1 10; n1 4;// n1 n1 4; System.out.println(n1); // 14 n1 / 3;// n1 n1 / 3;//4 System.out.println(n1); // 4
//复合赋值运算符会进行类型转换 byte b 3; b 2; // 等价 b (byte)(b 2); b; // b (byte)(b1); } }
4.6 三元运算符 4.6. 1基本语法 条件表达式 ? 表达式 1: 表达式 2; 运算规则
如果条件表达式为true 运算后的结果是表达式 1如果条件表达式为false 运算后的结果是表达式2 口诀: [一灯大师一真大师]
4.6.2案例演示 TernaryOperator.java
//三元运算符使用
public class TernaryOperator {
//编写一个 main 方法 public static void main(String[] args) {
int a 10; int b 99; // 解读 // 1. a b 为 false // 2. 返回 b–, 先返回 b 的值,然后在 b- 1 // 3. 返回的结果是 99 int result a b ? a : b–; System.out.println(“result” result); System.out.println(“a” a); System.out.println(“b” b);
} }
4.6.3使用细节 TernaryOperatorDetail.java
表达式 1 和表达式 2 要为可以赋给接收变量的类型(或可以自动转换)三元运算符可以转成 if–else 语句
int res a b ? a : --b; if ( a b) res a; else res --b;
//三元运算符细节
public class TernaryOperatorDetail {
//编写一个 main 方法 public static void main(String[] args) { //表达式 1 和表达式 2 要为可以赋给接收变量的类型 //(或可以自动转换/或者强制转换) int a 3; int b 8; int c a b ? (int)1. 1 : (int)3.4;//可以的 double d a b ? a : b 3;//可以的满足 int - double } }
4.6.4课堂练习 案例实现三个数的最大值 TernaryOperatorExercise.java
public class TernaryOperatorExercise {
//编写一个 main 方法 public static void main(String[] args) {
//案例实现三个数的最大值 int n1 553; int n2 33; int n3 123; //思路 //1. 先得到 n1 和 n2 中最大数 , 保存到 max1 //2. 然后再 求出 max1 和 n3 中的最大数保存到 max2
int max1 n1 n2 ? n1 : n2; int max2 max1 n3 ? max1 : n3; System.out.println(“最大数” max2);
//使用一条语句实现, 推荐使用上面方法 //老师提示: 后面我们可以使用更好方法, 比如排序 // int max (n1 n2 ? n1 : n2) n3 ? // (n1 n2 ? n1 : n2) : n3; // System.out.println(“最大数” max); //
int abcclass 10; int n 40; int N 50; System.out.println(“n” n);//40 System.out.println(“N” N);//50
//? abc 和 aBc 是两个不同变量
int abc 100; int aBc 200;
//int a b 300; //int a-b10; int goto1 10;
} }
4.7 运算符优先级
运算符有不同的优先级所谓优先级就是表达式运算中的运算顺序。如右表上一行运算符总优先于下一行。只有单目运算符、赋值运算符是从右向左运算的。一览表, 不要背使用多了就熟悉了.
4.8 标识符的命名规则和规范
4.8. 1判断下面变量名是否正确
hsp hsp12 1hsp h-s // //ok //ok //错误, 数字不能开头 错误 , 不能有 - x h // 错误 有空格 h$4 // ok class //错误class 关键字 int // 错误 ,int 是关键字 double //错误 ,double 是关键字 public //错误 ,public 是关键字 static //错误 ,static 是关键字 goto //错误, goto 是保留字 stu name //ok 4.8.2标识符命名规范[更加专业] 包名多单词组成时所有字母都小写aaa.bbb.ccc //比如 com.hsp.crm 类名、接口名多单词组成时所有单词的首字母大写XxxYyyZzz [大驼峰] 比如 TankShotGame 变量名、方法名多单词组成时第一个单词首字母小写第二个单词开始每个单词首字母大写xxxYyyZzz [小 驼峰 简称 驼峰法] 比如 tankShotGame 常量名所有字母都大写。多单词时每个单词用下划线连接XXX_YYY_ZZZ 比如 定义一个所得税率 TAX_RATE 后面我们学习到 类包接口等时我们的命名规范要这样遵守,更加详细的看文档.
4.9 关键字 关键字的定义和特点 (不用背) 定义被 Java语言赋予了特殊含义用做专门用途的字符串 (单词) 特点关键字中所有字母都为小写
10 保留字 1 介绍 Java 保留字现有 Java 版本尚未使用但以后版本可能会作为关键字使用。自己命名标识符时要避免使用这些保留 字 byValue 、cast 、future 、 generic 、 inner 、 operator 、 outer 、 rest 、 var 、 goto 、const 11 键盘输入语句 1 介绍 在编程中需要接收用户输入的数据就可以使用键盘输入语句来获取。Input.java , 需要一个 扫描器(对象), 就是 Scanner 11.2 步骤
导入该类的所在包, java.util.*创建该类对象 (声明变量)调用里面的功能
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 进制介绍 对于整数有四种表示方式 二进制0, 1 满 2 进 1. 以 0b 或 0B 开头。 十进制0-9 满 10 进 1。 八进制0-7 满 8 进 1. 以数字 0 开头表示。 十六进制0-9 及 A( 10)-F( 15) 满 16 进 1. 以 0x 或 0X 开头表示。此处的 A-F 不区分大小写。 4. 12.2 举例说明 BinaryTest.java
//演示四种进制 // public class BinaryTest {
//编写一个 main 方法 public static void main(String[] args) {
//n1 二进制 int n1 0b 1010; //n2 10 进制 int n2 1010; //n3 8 进制
int n3 01010; //n4 16 进制 int n4 0X10101; System.out.println(“n1” n1); System.out.println(“n2” n2); System.out.println(“n3” n3); System.out.println(“n4” n4); System.out.println(0x23A);
} } 4. 13 进制的图示
14 进制的转换(基本功) 1 进制转换的介绍
第一组 二进制转十进制 八进制转十进制 十六进制转十进制 第二组 十进制转二进制 十进制转八进制 十进制转十六进制 第三组 二进制转八进制 二进制转十六进制 第四组 八进制转二进制 十六进制转二进制 15 二进制转换成十进制示例 16 八进制转换成十进制示例 17 十六进制转换成十进制示例 规则从最低位(右边)开始将每个位上的数提取出来乘以 16 的(位数- 1)次方然后求和。 案例请将 0x23A 转成十进制的数 0x23A 10 * 16^0 3 * 16 ^ 1 2 * 16^2 10 48 512 570 课堂练习请将 0b 110001100 转成 十进制 02456 转成十进制 0xA45 转成十进制 18 十进制转换成二进制 规则将该数不断除以 2 直到商为 0 为止然后将每步得到的余数倒过来就是对应的二进制。 案例请将 34 转成二进制 0B00100010 19 十进制转换成八进制 规则将该数不断除以 8 直到商为 0 为止然后将每步得到的余数倒过来就是对应的八进制。 案例请将 131 转成八进制 0203
4.20 十进制转换成十六进制
规则将该数不断除以 16 直到商为 0 为止然后将每步得到的余数倒过来就是对应的十六进制。 案例请将 237 转成十六进制 0xED
课堂练习(一定练习使用计算器/用程序去验证) 123 转成 二进制 ?
678 转成八进制 ? 8912 转成十六进制 ? 4.21 二进制转换成八进制 规则从低位开始,将二进制数每三位一组转成对应的八进制数即可。 案例请将 ob 11010101 转成八进制 ob 11(3)010(2) 101(5) 0325 4.22 二进制转换成十六进制 规则从低位开始将二进制数每四位一组转成对应的十六进制数即可。 案例请将 ob 11010101 转成十六进制 ob 1101(D)0101(5) 0xD5 课堂练习请将 0b 11100101 转成 八进制 0b 1110010110 转成 十六进制 4.23 八进制转换成二进制 规则将八进制数每 1 位转成对应的一个 3 位的二进制数即可。 案例请将 0237 转成二进制 02(010)3(011)7( 111) 0b 10011111 4.24 十六进制转换成二进制 规则将十六进制数每 1 位转成对应的 4 位的一个二进制数即可。 案例请将 0x23B 转成二进制 0x2(0010)3(0011)B( 1011) 0b001000111011 课堂练习请将 01230 转成 二进制 0xAB29 转成二进制
4.25 位运算的思考题
请看下面的代码段回答 a,b,c,d,e 结果是多少? public static void maiin(String []args) { int a 12; // 1 向右位移 2 位 int b- 12;//算术右移 int c 12;//算术左移 int d- 12;// int e32;//无符号右移 //a,b,c,d,e 结果是多少 System.out.println(“a”a); System.out.println(“b”b); System.out.println(“c”c); System.out.println(“d”d); System.out.println(“e”e); }请回答在java 中下面的表达式运算的结果是: (位操作) 晚上练习 ~2? // 按位取反 23?// 2 按位与 3 2|3? ~-5? 137? 5|4? -33?// 按位异或 4.26 二进制在运算中的说明
4.27 原码、反码、补码(重点 难点)
4.28 位运算符 4.28. 1 java 中有 7 个位运算( 、| 、^ 、~ 、 、和 )
4.28.2 还有 3 个位运算符 、 和 , 运算规则:
算术右移 低位溢出,符号位不变,并用符号位补溢出的高位算术左移 : 符号位不变,低位补 0 逻辑右移也叫无符号右移,运算规则是: 低位溢出高位补 0 特别说明没有 符号 4.28.3 应用案例 BitOperator02.javaint a 12; //1 00000001 00000000 本质 1 / 2 / 2 0int c 12; //1 00000001 00000100 本质 1 * 2 * 2 4 4.28.4 完成前面的案例 建议掌握老师讲解的即可不用再深入. 4.29 本章作业
第 5 章 程序控制结构 5. 1 程序流程控制介绍 在程序中程序运行的流程控制决定程序是如何执行的是我们必须掌握的主要有三大流程控制语句。
顺序控制分支控制循环控制 5.2 顺序控制
5.3 分支控制 if-else 5.3. 1分支控制 if-else 介绍 让程序有选择的的执行,分支控制有三种
单分支 if双分支 if-else多分支 if-else if -…-else
5.3.2单分支
//if 的快速入门 import java.util.Scanner;//导入 public class If01 {
//编写一个 main 方法 public static void main(String[] args) { //编写一个程序,可以输入人的年龄,如果该同志的年龄大于 18 岁, //则输出 “你年龄大于 18,要对自己的行为负责,送入监狱” // //思路分析 //1. 接收输入的年龄, 应该定义一个 Scanner 对象 //2. 把年龄保存到一个变量 int age //3. 使用 if 判断输出对应信息 //应该定义一个 Scanner 对象
Scanner myScanner new Scanner(System.in); System.out.println(“请输入年龄”); //把年龄保存到一个变量 int age int age myScanner.nextInt(); //使用 if 判断输出对应信息 if(age 18) { System.out.println(“你年龄大于 18,要对自己的行为负责,送入监狱”); }
System.out.println(“程序继续…”);
} }
5.4 双分支
//if-else 的快速入门 import java.util.Scanner;//导入 public class If02 {
//编写一个 main 方法 public static void main(String[] args) { //编写一个程序,可以输入人的年龄,如果该同志的年龄大于 18 岁, //则输出 “你年龄大于 18,要对 //自己的行为负责, 送入监狱” 。否则 ,输出你的年龄不大这次放过你了.
// //思路分析 //1. 接收输入的年龄, 应该定义一个 Scanner 对象 //2. 把年龄保存到一个变量 int age //3. 使用 if-else 判断输出对应信息
//应该定义一个 Scanner 对象 Scanner myScanner new Scanner(System.in); System.out.println(“请输入年龄”); //把年龄保存到一个变量 int age int age myScanner.nextInt(); //使用 if-else 判断输出对应信息 if(age 18) { System.out.println(“你年龄大于 18,要对自己的行为负责,送入监狱”); } else {//双分支 System.out.println(“你的年龄不大这次放过你了”); }
System.out.println(“程序继续…”);
} } 5.4. 1双分支
5.4.2单分支和双分支练习题
//IfExercise01.java
编写程序声明2 个 double 型变量并赋值。判断第一个数大于 10.0 且第 2 个数小于 20.0 打印两数之和。 【课后自己练】定义两个变量int 判断二者的和是否能被 3 又能被 5 整除打印提示信息判断一个年份是否是闰年闰年的条件是符合下面二者之一( 1)年份能被 4 整除但不能被 100 整除(2)能被 400 整除代码
//单分支和双分支的练习 // public class IfExercise01 {
//编写一个 main 方法 public static void main(String[] args) {
//编写程序声明2 个 double 型变量并赋值。 //判断第一个数大于 10.0 且第 2 个数小于 20.0 打印两数之和
//思路分析
double d 1 33.5; double d2 2.6; if(d1 10.0 d2 20.0) { System.out.println(“两个数和” (d1 d2)); }
//【课后自己练】定义两个变量int 判断二者的和 //是否能被 3 又能被 5 整除打印提示信息 // //思路分析 //1. 定义两个变量 int num1, num2 //2. 定义一个变量 int sum num1 num2; //3. sum % 3 , 5 后 等于 0 说明可以整除 //4. 使用 if - else 来提示对应信息 //走代码 int num1 10; int num2 1; int sum num1 num2; if(sum % 3 0 sum % 5 0) { System.out.println(“和可以被 3 又能被 5 整除”); } else { System.out.println(“和不能被 3 和 5 整除…”); }
//判断一个年份是否是闰年闰年的条件是符合下面二者之一 //(1)年份能被 4 整除但不能被 100 整除(2)能被 400 整除 // //思路分析 //1. 定义 int year 保存年 //2. 年份能被 4 整除但不能被 100 整除, // year % 4 0 year % 100 ! 0 //3. 能被 400 整除 year % 400 0 //4. 上面的 2 和 3 是 或的关系 //代码实现 int year 2028; if( (year % 4 0 year % 100 ! 0) || year % 400 0 ) { System.out.println(year 是 闰年); } else { System.out.println(year 不是 闰年); } } } 5.4.3多分支
多分支的流程图(重要!)5.4.4多分支 案例演示 1 请大家看个案例[If03.java]: 输入保国同志的芝麻信用分 如果 信用分为 100 分时输出 信用极好 信用分为(80 99]时输出 信用优秀 信用分为[60,80]时输出 信用一般 其它情况 输出 信用 不及格 请从键盘输入保国的芝麻信用分并加以判断 代码:
//课堂练习 import java.util.Scanner; public class If03 {
//编写一个 main 方法 public static void main(String[] args) { /* 输入保国同志的芝麻信用分 如果 信用分为 100 分时输出 信用极好 信用分为(80 99]时输出 信用优秀 信用分为[60,80]时输出 信用一般 其它情况 输出 信用 不及格 请从键盘输入保国的芝麻信用分并加以判断 假定信用分数为int */
Scanner myScanner new Scanner(System.in); //接收用户输入 System.out.println(“请输入信用分(1- 100):”); //请思考如果小伙伴输入的不是整数而是hello… //这里我们后面可以使用异常处理机制搞定- 》老师点一下
int grade myScanner.nextInt();
//先对输入的信用分进行一个范围的有效判断 1- 100, 否则提示输入错误
if(grade 1 grade 100) { //因为有 4 种情况所以使用多分支 if(grade 100) { System.out.println(“信用极好”); } else if (grade 80 grade 99) { //信用分为(80 99]时输出 信用优秀 System.out.println(“信用优秀”); } else if (grade 60 grade 80) {//信用分为[60,80]时输出 信用一般 System.out.println(“信用一般”); } else {//其它情况 输出 信用 不及格 System.out.println(“信用不及格”); }
} else { System.out.println(“信用分需要在 1- 100,请重新输入:)”); }
} }
案例演示 2
5.5 嵌套分支 5.5. 1基本介绍 在一个分支结构中又完整的嵌套了另一个完整的分支结构里面的分支的结构称为内层分支外面的分支结构称为外 层分支。老师建议: 不要超过 3 层 (可读性不好) 5.5.2基本语法
5.5.3应用案例 参加歌手比赛如果初赛成绩大于 8.0 进入决赛否则提示淘汰。并且根据性别提示进入男子组或女子组。【可以 让学员先练习下】, 输入成绩和性别进行判断和输出信息。[NestedIf.java] 提示: double score; char gender; 接收字符: char gender scanner.next().charAt(0)
import java.util.Scanner;
public class NestedIf {
//编写一个 main 方法 public static void main(String[] args) { /* 参加歌手比赛如果初赛成绩大于 8.0 进入决赛 否则提示淘汰。并且根据性别提示进入男子组或女子组。 【可以让学员先练习下】, 输入成绩和性别进行判断和输出信息。 [NestedIf.java]
提示: double score; char gender; 接收字符: char gender scanner.next().charAt(0)
*/ //思路分析 //1. 创建 Scanner 对象接收用户输入 //2. 接收 成绩保存到 double score //3. 使用 if-else 判断 如果初赛成绩大于 8.0 进入决赛否则提示淘汰 //4. 如果进入到 决赛再接收 char gender, 使用 if-else 输出信息 //代码实现 思路 -- java 代码
Scanner myScanner new Scanner(System.in); System.out.println(“请输入该歌手的成绩”); double score myScanner.nextDouble(); if( score 8.0 ) { System.out.println(“请输入性别”);
char gender myScanner.next().charAt(0); if( gender ‘男’ ) { System.out.println(“进入男子组”); } else if(gender ‘女’) { System.out.println(“进入女子组”); } else { System.out.println(“你的性别有误不能参加决赛~”); } } else { System.out.println(“sorry ,你被淘汰了~”); } } }
5.5.4应用案例 2, 一定自己做.
5.6 switch 分支结构 5.6. 1基本语法
5.6.2流程图
画出 swtich 出流程案例说明流程图
5.6.3快速入门 案例Switch01.java 请编写一个程序该程序可以接收一个字符比如:a,b,c,d,e,f,g a 表示星期一b 表示星期二 …
根据用户的输入显示相应的信息.要求使用 switch 语句完成 代码
import java.util.Scanner; public class Switch01 {
//编写一个 main 方法 public static void main(String[] args) { /* 案例Switch01.java 请编写一个程序该程序可以接收一个字符比如:a,b,c,d,e,f,g a 表示星期一b 表示星期二 … 根据用户的输入显示相应的信息.要求使用 switch 语句完成
思路分析
接收一个字符 , 创建 Scanner 对象使用 switch 来完成匹配,并输出对应信息 代码
*/ Scanner myScanner new Scanner(System.in); System.out.println(“请输入一个字符(a-g)”); char c1 myScanner.next().charAt(0);// //在java 中只要是有值返回就是一个表达式 switch(c1) { case ‘a’ :
System.out.println(“今天星期一,猴子穿新衣”); break; case ‘b’ : System.out.println(“今天星期二,猴子当小二”); break; case ‘c’ : System.out.println(“今天星期三,猴子爬雪山…”); break; //… default: System.out.println(“你输入的字符不正确没有匹配的”); }
System.out.println(“退出了 switch ,继续执行程序”); } } 5.6.4switch 注意事项和细节讨论
5.6.5switch 课堂练习(学员先做) SwitchExercise.java
使用 switch 把小写类型的 char 型转为大写(键盘输入) 。只转换 a, b, c, d, e. 其它的输出 “other”。对学生成绩大于 60 分的输出合格 。低于 60 分的输出不合格 。(注输入的成绩不能大于 100), 提示 成绩/60根据用于指定月份打印该月份所属的季节。3,4,5 春季 6,7,8 夏季 9, 10, 11 秋季 12, 1, 2 冬季 [课堂练习, 提示 使 用穿透 ] 代码:
import java.util.Scanner; public class SwitchExercise {
//编写一个 main 方法 public static void main(String[] args) { //使用 switch 把小写类型的
//char 型转为大写(键盘输入) 。只转换 a-A, b-B, c, d, e. //其它的输出 “other”。
//创建 Scanner 对象 // Scanner myScanner new Scanner(System.in); // System.out.println(“请输入 a-e”); // char c1 myScanner.next().charAt(0); // switch(c1) { // case ‘a’ : // System.out.println(“A”); // break; // case ‘b’ : // System.out.println(“B”); // break; // case ‘c’ : // System.out.println(“C”); // break; // case ‘d’ : // System.out.println(“D”); // break; // case ‘e’ : // System.out.println(“E”); // break; // default : // System.out.println(“你的输入有误~”);
// }
//对学生成绩大于 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; // default : // System.out.println(“输入有误”);
} } else { System.out.println(“输入的成绩在 0- 100”); }
//根据用于指定月份 //打印该月份所属的季节。 //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.6switch 和 if 的比较
如果判断的具体数值不多而且符合 byte 、 short 、int 、 char, enum[枚举], String 这 6 种类型。虽然两个语句都可 以使用建议使用 swtich 语句。其他情况对区间判断对结果为 boolean 类型判断使用ifif的使用范围更广 5.7 for 循环控制(!!!)
基本介绍:听其名而知其意,就是让你的代码可以循环的执行. 5.7. 1看一个实际需求 请大家看个案例[For01.java]:编写一个程序, 可以打印 10 句 “你好韩顺平教育!” 。请大家想想怎么做? 5.7.2基本语法
老韩说明
for 关键字表示循环控制for 有四要素: ( 1)循环变量初始化(2)循环条件(3)循环操作(4)循环变量迭代循环操作 , 这里可以有多条语句也就是我们要循环执行的代码如果 循环操作(语句) 只有一条语句可以省略 {}, 建议不要省略 5.7.3 for 循环执行流程分析 使用for 循环完成前面的题 画出 for 流程图 代码执行, 内存分析法(初学者)图
5.7.4注意事项和细节说明 ForDetail.java 循环条件是返回一个布尔值的表达式 for(;循环判断条件;) 中的初始化和变量迭代可以写到其它地方但是两边的分号不能省略。 循环初始值可以有多条初始化语句但要求类型一样并且中间用逗号隔开循环变量迭代也可以有多条变量迭代 语句中间用逗号隔开。 使用内存分析法老师分析输出下面代码输出什么?
5.7.5 for 循环练习题(学员先做) ForExercise.java
打印 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);
} }
完成下面的表达式输出 [老师评讲 ForExercise02.java]
public class ForExercise02 {
//编写一个 main 方法 public static void main(String[] args) {
//化繁为简 //先死后活 int n 9; for( int i 0; i n; i) { System.out.println(i “” (n-i) “” n); } } } 5.8 while 循环控制 5.8. 1基本语法
5.8.2while 循环执行流程分析 While01.java 画出流程图 使用 while 循环完成前面的题
//while 循环的案例 // public class While01 {
//编写一个 main 方法 public static void main(String[] args) {
//输出 10 句 你好,韩顺平教育
int i 1; //循环变量初始化 while( i 10 ) {//循环条件 System.out.println(“你好韩顺平教育” i);//执行语句 i;//循环变量迭代 }
System.out.println(“退出 while 继续…” i); // 11 } }
代码执行内存分析图
5.8.3注意事项和细节说明
循环条件是返回一个布尔值的表达式while 循环是先判断再执行语句 5.8.4课堂练习题[学员先做] WhileExercise.java打印 1— 100 之间所有能被 3 整除的数 [使用 while, 老师评讲 ]打印 40—200 之间所有的偶数 [使用 while, 课后练习] 代码
public class WhileExercise {
//编写一个 main 方法 public static void main(String[] args) {
// 打印 1— 100 之间所有能被 3 整除的数 [使用 while, 老师评讲 ] // 化繁为简, 先死后活
int i 1; int endNum 100; while( i endNum) { if( i % 3 0) { System.out.println(“i” i); }
i;//变量自增
}
// 打印 40—200 之间所有的偶数 [使用 while, 课后练习] // 化繁为简, 先死后活(利于思考) // System.out.println(“”); int j 40; //变量初始化 while ( j 200) { //判断 if( j % 2 0) { System.out.println(“j” j); } j;//循环变量的迭代 }
} }
5.9 do…while 循环控制 5.9. 1基本语法 循环变量初始化; do{ 循环体(语句); 循环变量迭代; }while(循环条件);
5.9.2老韩说明:
do while 是关键字也有循环四要素, 只是位置不一样先执行再判断也就是说一定会至少执行一次最后 有一个 分号 ;while 和 do…while 区别举例: 要账 5.9.3do…while 循环执行流程分析 DoWhile01.java 画出流程图 使用 do…while 循环完成前面的题 代码执行内存分析图
5.9.4注意事项和细节说明
循环条件是返回一个布尔值的表达式do…while 循环是先执行再判断 因此它至少执行一次 5.9.5课堂练习题【学员先做】打印 1— 100 [学生做]计算 1— 100 的和 [学生做]统计 1—200 之间能被 5 整除但不能被 3 整除的个数 (DoWhileExercise01.java)
public class DoWhileExercise01 {
//编写一个 main 方法 public static void main(String[] args) { //统计 1—200 之间能被 5 整除但不能被 3 整除的 个数
//化繁为简 //(1) 使用 do-while 输出 1-200 //(2) 过滤 能被 5 整除但不能被 3 整除的数 % //(3) 统计满足条件的个数 int count 0; //先死后活 //(1) 范围的值 1-200 你可以做出变量 //(2) 能被 5 整除但不能被 3 整除的 , 5 和 3 可以改成变量 int i 1; int count 0;//统计满足条件的个数 do { if( i % 5 0 i % 3 ! 0 ) { System.out.println(“i” i); count; } i; }while(i 200);
System.out.println(“count” count); } }
如果李三不还钱则老韩将一直使出五连鞭直到李三说还钱为止 [System.out.println(“老韩问还钱吗y/n”)] do…while … DoWhileExercise02.java
import java.util.Scanner; public class DoWhileExercise02 {
//编写一个 main 方法 public static void main(String[] args) {
//如果李三不还钱则老韩将一直使出五连鞭直到李三说还钱为 //[System.out.println(“老韩问还钱吗y/n”)] do…while … // //化繁为简 //(1) 不停的问还钱吗? //(2) 使用 char answer 接收回答, 定义一个 Scanner 对象 //(3) 在 do-while 的 while 判断如果是 y 就不在循环 //一定自己动脑筋… Scanner myScanner new Scanner(System.in); char answer ’ ; do { System.out.println(“老韩使出五连鞭~”); System.out.println(“老韩问还钱吗y/n”); answer myScanner.next().charAt(0); System.out.println(“他的回答是” answer); }while(answer ! ‘y’);//判断条件很关键
System.out.println(“李三还钱了”); } }
10 多重循环控制(难点! 重点!) 1 介绍 将一个循环放在另一个循环体内就形成了嵌套循环。其中for ,while ,do …while 均可以作为外层循环和内层循环。 【建议一般使用两层最多不要超过 3 层, 否则代码的可读性很差】 实质上嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为false 时才会完全跳出内 层循环才可结束外层的当次循环开始下一次的循环[听不懂走案例]。 设外层循环次数为 m 次内层为 n 次则内层循环体实际上需要执行 m*n 次。 10.2 多重循环执行步骤分析 请分析 下面的多重循环执行步骤, 并写出输出 韩老师的内存分析法 //双层 for MulFor.java for(int i 0; i 2; i) { //先思考 for( int j 0; j 3; j) { System.out.println(“i” i j j); } } 10.3 应用实例 //MulForExercise01.java
统计 3 个班成绩情况每个班有 5 名同学求出各个班的平均分和所有班级的平均分[学生的成绩从键盘输入]。统计三个班及格人数每个班有 5 名同学。
import java.util.Scanner; public class MulForExercise01 {
//编写一个 main 方法 public static void main(String[] args) { //统计 3 个班成绩情况每个班有 5 名同学 //求出各个班的平均分和所有班级的平均分[学生的成绩从键盘输入]。 //统计三个班及格人数每个班有 5 名同学。 // //思路分析:
//化繁为简 //(1) 先计算一个班 , 5 个学生的成绩和平均分 , 使用 for //1. 1 创建 Scanner 对象然后接收用户输入 //1.2 得到该班级的平均分 , 定义一个 doubel sum 把该班级 5 个学生的成绩累积
//(2) 统计 3 个班(每个班 5 个学生) 平均分 //(3) 所有班级的平均分 //3. 1 定义一个变量double totalScore 累积所有学生的成绩 //3.2 当多重循环结束后totalScore / (3 * 5) //(4) 统计三个班及格人数 //4. 1 定义变量 int passNum 0; 当有一个学生成绩60, passNum //4.2 如果 60 passNum //(5) 可以优化[效率可读性, 结构]
//创建 Scanner 对象 Scanner myScanner new Scanner(System.in); double totalScore 0; //累积所有学生的成绩 int passNum 0;//累积 及格人数 int classNum 3; //班级个数 int stuNum 5;//学生个数 for( int i 1; i classNum; i) {//i 表示班级
double sum 0; //一个班级的总分 for( int j 1;j stuNum;j) {//j 表示学生 System.out.println(“请数第”i“个班的第”j“个学生的成绩”); double score myScanner.nextDouble();
//当有一个学生成绩60, passNum if(score 60) { passNum; } sum score; //累积 System.out.println(“成绩为” score); } //因为 sum 是 5 个学生的总成绩 System.out.println(“sum” sum 平均分 (sum / stuNum)); //把 sum 累积到 totalScore totalScore sum;
} System.out.println(“三个班总分” totalScore 平均分 totalScore / (classNum*stuNum)); System.out.println(“及格人数” passNum);
} }
打印出九九乘法表[课后题]
10.4 经典的打印金字塔 使用 for 循环完成下面的案例 请编写一个程序可以接收一个整数,表示层数 (totalLevel) 打印出金字塔。(Stars.java) [化繁为简, 先死后活]
public class Stars {
//编写一个 main 方法 public static void main(String[] args) { /* *思路分析 化繁为简
先打印一个矩形 打印半个金字塔 //第 1 层 有 1 个* //第 2 层 有 2 个* //第 3 层 有 3 个* //第 4 层 有 4 个* //第 5 层 有 5 个*
打印整个金字塔 //第 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(”); } } }
11 跳转控制语句-break 1 看下面一个需求 随机生成 1- 100 的一个数直到生成了97 这个数看看你一共用了几次? 提示使用 (int)(Math.random() * 100) 1 思路分析 循环但是循环的次数不知道. - break , 当某个条件满足时终止循环 通过该需求可以说明其它流程控制的必要性比如break 11.2 基本介绍 break 语句用于终止某个语句块的执行一般使用在 switch 或者循环[for , while , do-while]中11.3 基本语法 { … … break;
… … } 5. 11.4 以 while 使用 break 为例,画出示意图 11.5 快速入门: Break01.java 11.6 注意事项和细节说明 11.7 课堂练习题
BreakExercise.java
1- 100 以内的数求和求出 当和 第一次大于 20 的当前数 【for break】
public class BreakExercise {
//编写一个 main 方法 public static void main(String[] args) { //1- 100 以内的数求和求出 当和 第一次大于 20 的当前数 【for break】
//思路分析 //1. 循环 1- 100, 求和 sum //2. 当 sum 20 时记录下当前数然后 break //3. 在 for 循环外部定义变量 n , 把当前 i 赋给 n int sum 0; //累积和
//注意 i 的作用范围在 for{} int n 0; for(int i 1; i 100; i) { sum i;//累积 if(sum 20) { System.out.println(“和20 时候 当前数 i” i); n i; break; } }
System.out.println(“当前数” n); }
}
实现登录验证有 3 次机会如果用户名为丁真 ,密码666提示登录成功否则提示还有几次机会请使用forbreak 完成 BreakExercise02.java
import java.util.Scanner; public class BreakExercise02 {
//编写一个 main 方法 public static void main(String[] args) {
//实现登录验证有 3 次机会如果用户名为丁真 ,密码666提示登录成功 //否则提示还有几次机会请使用 forbreak 完成 // // 思路分析 // 1. 创建 Scanner 对象接收用户输入 // 2. 定义 String name ; String passwd; 保存用户名和密码 // 3. 最多循环 3 次[登录 3 次] 如果 满足条件就提前退出 // 4. 定义一般变量 int chance 记录还有几次登录机会 // // 代码实现
Scanner myScanner new Scanner(System.in); String name “”; String passwd “”; int chance 3; //登录一次 就减少一次 for( int i 1; i 3; i) {//3 次登录机会
System.out.println(“请输入名字”); name myScanner.next(); System.out.println(“请输入密码”); passwd myScanner.next(); //比较输入的名字和密码是否正确 //补充说明字符串 的内容 比较 使用的 方法 equals if(“丁真”.equals(name) “666”.equals(passwd)) { System.out.println(“恭喜你登录成功~”); break; }
//登录的机会就减少一次 chance–; System.out.println(“你还有” chance “次登录机会”); }
} } 5. 12 跳转控制语句-continue 5. 12. 1 基本介绍
continue 语句用于结束本次循环继续执行下一次循环。continue 语句出现在多层嵌套的循环语句体中时可以通过标签指明要跳过的是哪一层循环 , 这个和前面的标签的 使用的规则一样.
12.2 基本语法 { … … continue;
… … } 5. 12.3 以 while 使用 continue 为例,画出示意图 12.4 快速入门案例 Continue01.java 12.5 细节案例分析和说明 ContinueDetail.java
label 1: for(int j 0; j 4; j){ label2: for(int i 0; i 10; i){ if(i 2){ //看看分别输出什么值并分析 //continue ; //continue label2; continue label 1; } System.out.println(i i); } }
13 跳转控制语句-return return 使用在方法表示跳出所在的方法在讲解方法的时候会详细的介绍这里我们简单的提一下。注意如
果 return 写在 main 方法退出程序…Return01.java
14 本章作业
第 6 章 数组、排序和查找 6. 1 为什么需要数组 一个养鸡场有 6 只鸡它们的体重分别是 3kg,5kg, 1kg,3.4kg,2kg,50kg 。请问这六只鸡的总体重是多少?平 均体重是多少? 请你编一个程序。 Array01.java 思路 定义 6 个变量 , 加起来 总体重 求出平均体重. 引出 - 数组 6. 1. 1数组介绍 数组可以存放多个同一类型的数据。数组也是一种数据类型是引用类型。 即数(数据)组(一组)就是一组数据 6. 1.2 数组快速入门 Array01.java 比如我们可以用数组来解决上一个问题。 体验
//数组的引出 // public class Array01 {
//编写一个 main 方法 public static void main(String[] args) { /* 它们的体重分别是 3kg,5kg, 1kg,3.4kg,2kg,50kg 。 请问这六只鸡的总体重是多少?平均体重是多少?
思路分析
定义六个变量 double , 求和 得到总体重平均体重 总体重 / 6分析传统实现的方式问题. 6-600-566引出新的技术 - 使用数组来解决. */
// double hen1 3; // double hen2 5; // double hen3 1; // double hen4 3.4; // double hen5 2; // double hen6 50;
// double totalWeight hen1 hen2 hen3 hen4 hen5 hen6;
// double avgWeight totalWeight / 6; // System.out.println(“总体重” totalWeight // “平均体重” avgWeight);
//比如我们可以用数组来解决上一个问题 体验 // //定义一个数组 //老韩解读 //1. double[] 表示 是 double 类型的数组 数组名 hens //2. {3, 5, 1, 3.4, 2, 50} 表示数组的值/元素,依次表示数组的 // 第几个元素
// double[] hens {3, 5, 1, 3.4, 2, 50, 7.8, 88.8, 1. 1,5.6, 100};
//遍历数组得到数组的所有元素的和 使用for //老韩解读 //1. 我们可以通过 hens[下标] 来访问数组的元素 // 下标是从 0 开始编号的比如第一个元素就是 hens[0] // 第 2 个元素就是 hens[ 1] , 依次类推 //2. 通过 for 就可以循环的访问 数组的元素/值 //3. 使用一个变量 totalWeight 将各个元素累积 System.out.println(“使用数组解决”); //老师提示 可以通过 数组名.length 得到数组的大小/长度 //System.out.println(“数组的长度” hens.length); double totalWeight 0; for( int i 0; i hens.length; i) { //System.out.println(“第” (i1) “个元素的值” hens[i]); totalWeight hens[i]; }
System.out.println(“总体重” totalWeight
“平均体重” (totalWeight / hens.length) );
} }
6.2 数组的使用
import java.util.Scanner; public class Array02 {
//编写一个 main 方法 public static void main(String[] args) { //演示 数据类型 数组名[]new 数据类型[大小] //循环输入 5 个成绩保存到 double 数组,并输出
//步骤 //1. 创建一个 double 数组大小 5
//(1) 第一种动态分配方式 //double scores[] new double[5]; //(2) 第 2 种动态分配方式 先声明数组再 new 分配空间 double scores[] ; //声明数组 这时 scores 是 null scores new double[5]; // 分配内存空间可以存放数据
//2. 循环输入 // scores.length 表示数组的大小/长度 // Scanner myScanner new Scanner(System.in); for( int i 0; i scores.length; i) { System.out.println(“请输入第” (i1) “个元素的值”); scores[i] myScanner.nextDouble(); }
//输出遍历数组 System.out.println(“数组的元素/值的情况如下:”); for( int i 0; i scores.length; i) { System.out.println(“第” (i1) “个元素的值” scores[i]); } }
} 6.2. 1使用方式 2-动态初始化 先声明数组 语法:数据类型 数组名[]; 也可以 数据类型[] 数组名; int a[]; 或者 int[] a; 创建数组 语法: 数组名new 数据类型[大小]; anew int[10]; 案例演示【前面修改即可】 6.2.2使用方式 3-静态初始化
6.3 数组使用注意事项和细节
数组是多个相同类型数据的组合实现对这些数据的统一管理数组中的元素可以是任何数据类型包括基本类型和引用类型但是不能混用。数组创建后如果没有赋值有默认值 int 0 short 0, byte 0, long 0, float 0.0,double 0.0 char \u0000 boolean false String null使用数组的步骤 1. 声明数组并开辟空间 2 给数组各个元素赋值 3 使用数组数组的下标是从 0 开始的。数组下标必须在指定范围内使用否则报下标越界异常比如
int [] arrnew int[5]; 则有效下标为 0-4 7) 数组属引用类型数组型数据是对象(object) 代码:
public class ArrayDetail {
//编写一个 main 方法 public static void main(String[] args) { //1. 数组是多个相同类型数据的组合实现对这些数据的统一管理
//int[] arr1 { 1, 2, 3, 60,“hello”};//String -int double[] arr2 { 1. 1, 2.2, 3.3, 60.6, 100};//int -double
//2. 数组中的元素可以是任何数据类型包括基本类型和引用类型但是不能混用 String[] arr3 {“北京”,“jack”,“milan”};
//3. 数组创建后如果没有赋值有默认值 //int 0 short 0, byte 0, long 0, //float 0.0,double 0.0 char \u0000 //boolean false String null // short[] arr4 new short[3]; System.out.println(“数组 arr4”); for(int i 0; i arr4.length; i) { System.out.println(arr4[i]); }
//6. 数组下标必须在指定范围内使用否则报下标越界异常比如 //int [] arrnew int[5]; 则有效下标为 0-4 //即数组的下标/索引 最小 0 最大 数组长度- 1(4) int [] arr new int[5]; //System.out.println(arr[5]);//数组越界
} }
6.4 数组应用案例
创建一个 char 类型的 26 个元素的数组分别 放置’A’-‘Z’ 。使用 for 循环访问所有元素并打印出来。提示char 类型 数据运算 ‘A’2 - ‘C’ ArrayExercise01.java
public class ArrayExercise01 {
//编写一个 main 方法 public static void main(String[] args) {
/* 创建一个 char 类型的 26 个元素的数组分别 放置’A’-‘Z’。 使用for 循环访问所有元素并打印出来。 提示char 类型数据运算 ‘A’ 1 - ‘B’
思路分析
定义一个 数组 char[] chars new char[26]因为 ‘A’ 1 ‘B’ 类推所以老师使用 for 来赋值使用for 循环访问所有元素 */ char[] chars new char[26]; for( int i 0; i chars.length; i) {//循环 26 次 //chars 是 char[] //chars[i] 是 char chars[i] (char)(‘A’ i); //‘A’ i 是 int , 需要强制转换 }
//循环输出 System.out.println(“chars 数组”); for( int i 0; i chars.length; i) {//循环 26 次 System.out.print(chars[i] ); }
} }
请求出一个数组 int[]的最大值 {4,- 1,9, 10,23} 并得到对应的下标。 ArrayExercise02.java
public class ArrayExercise02 {
//编写一个 main 方法 public static void main(String[] args) {
//请求出一个数组 int[]的最大值 {4,- 1,9, 10,23} 并得到对应的下标 //老韩思路分析 //1. 定义一个 int 数组 int[] arr {4,- 1,9, 10,23}; //2. 假定 max arr[0] 是最大值 , maxIndex0; //3. 从下标 1 开始遍历 arr 如果 max 当前元素说明 max 不是真正的 // 最大值, 我们就 max当前元素; maxIndex当前元素下标 //4. 当我们遍历这个数组 arr 后 , max 就是真正的最大值maxIndex 最大值 // 对应的下标
int[] arr {4,- 1,9, 10,23}; int max arr[0];//假定第一个元素就是最大值 int maxIndex 0; //
for(int i 1; i arr.length; i) {//从下标 1 开始遍历 arr
if(max arr[i]) {//如果 max 当前元素 max arr[i]; //把 max 设置成 当前元素 maxIndex i; } } //当我们遍历这个数组 arr 后 , max 就是真正的最大值maxIndex 最大值下标 System.out.println(“max” max maxIndex maxIndex); } }
请求出一个数组的和和平均值。(养鸡场) 6.5 数组赋值机制基本数据类型赋值这个值就是具体的数据而且相互不影响。 int n1 2; int n2 n1;数组在默认情况下是引用传递赋的值是地址。 看一个案例并分析数组赋值的内存图(重点, 难点. )。 //代码 ArrayAssign.java int[] arr1 { 1,2,3}; int[] arr2 arr1;
6.6 数组拷贝 编写代码 实现数组拷贝(内容复制)ArrayCopy.java 将 int[] arr1 { 10,20,30}; 拷贝到 arr2 数组, 要求数据空间是独立的.
public class ArrayCopy {
//编写一个 main 方法 public static void main(String[] args) {
//将 int[] arr1 { 10,20,30}; 拷贝到 arr2 数组, //要求数据空间是独立的.
int[] arr1 { 10,20,30};
//创建一个新的数组 arr2,开辟新的数据空间 //大小 arr1.length; int[] arr2 new int[arr1.length];
//遍历 arr1 把每个元素拷贝到 arr2 对应的元素位置 for(int i 0; i arr1.length; i) { arr2[i] arr1[i]; }
//老师修改 arr2 不会对 arr1 有影响. arr2[0] 100;
//输出 arr1 System.out.println(“arr1 的元素”); for(int i 0; i arr1.length; i) { System.out.println(arr1[i]);//10,20,30 }
// System.out.println(“arr2 的元素”); for(int i 0; i arr2.length; i) { System.out.println(arr2[i]);// }
} }
6.7 数组反转 要求把数组的元素内容反转。 ArrayReverse.java arr { 11,22,33,44,55,66} {66, 55,44,33,22, 11} //思考 2min 方式 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 使用逆序赋值方式 【思路分析, 学员自己完成】 ArrayReverse02.java
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.8 数组添加/扩容 要求实现动态的给数组添加元素效果实现对数组扩容。ArrayAdd.java 原始数组使用静态分配 int[] arr { 1,2,3} 增加的元素 4 直接放在数组的最后 arr { 1,2,3,4} 用户可以通过如下方法来决定是否继续添加添加成功是否继续y/n ArrayAdd02.java 2min-试试 2min 思考- 》试试 代码
import java.util.Scanner;
public class ArrayAdd02 {
//编写一个 main 方法 public static void main(String[] args) { /* 要求实现动态的给数组添加元素效果实现对数组扩容。ArrayAdd.java 1.原始数组使用静态分配 int[] arr { 1,2,3} 2.增加的元素 4 直接放在数组的最后 arr { 1,2,3,4} 3.用户可以通过如下方法来决定是否继续添加添加成功是否继续y/n
思路分析
定义初始数组 int[] arr {1,2,3}//下标 0-2定义一个新的数组 int[] arrNew new int[arr.length1];遍历 arr 数组依次将 arr 的元素拷贝到 arrNew 数组将 4 赋给 arrNew[arrNew.length - 1] 4;把 4 赋给 arrNew 最后一个元素让 arr 指向 arrNew ; arr arrNew; 那么 原来 arr 数组就被销毁创建一个 Scanner 可以接受用户输入因为用户什么时候退出不确定老师使用 do-while break 来控制 */
Scanner myScanner new Scanner(System.in); //初始化数组 int[] arr { 1,2,3};
do { int[] arrNew new int[arr.length 1];
//遍历 arr 数组依次将 arr 的元素拷贝到 arrNew 数组 for(int i 0; i arr.length; i) { arrNew[i] arr[i]; } System.out.println(“请输入你要添加的元素”); int addNum myScanner.nextInt(); //把 addNum 赋给 arrNew 最后一个元素 arrNew[arrNew.length - 1] addNum; //让 arr 指向 arrNew, arr arrNew; //输出 arr 看看效果 System.out.println(“arr 扩容后元素情况”); for(int i 0; i arr.length; i) { System.out.print(arr[i] “\t”); } //问用户是否继续 System.out.println(“是否继续添加 y/n”); char key myScanner.next().charAt(0); if( key ‘n’) { //如果输入 n ,就结束 break; } }while(true);
System.out.println(“你退出了添加…”); } }
课后练习题: ArrayReduce.java 有一个数组 { 1 2 3 4 5} 可以将该数组进行缩减提示用户是否继续缩减每次缩减最后那个元素。当只剩 下最后一个元素提示不能再缩减。
6.9 排序的介绍 排序是将多个数据依指定的顺序进行排列的过程。 排序的分类 6.9. 1内部排序: 指将需要处理的所有数据都加载到内部存储器中进行排序。包括(交换式排序法、选择 式排序法和插入式排序法)
6.9.2外部排序法 数据量过大无法全部加载到内存中需要借助外部存储进行排序。包括(合并排序法和直接合并排序法)。 6. 10 冒泡排序法 冒泡排序 (Bubble Sorting) 的基本思想是通过对待排序序列从后向前 (从下标较大的元素开始) 依次比较相邻元素 的值若发现逆序则交换使值较大的元素逐渐从前移向后部就象水底下的气泡一样逐渐向上冒。
11 冒泡排序法
冒泡排序法案例 BubbleSort.java 下面我们举一个具体的案例来说明冒泡法。我们将五个无序24,69,80,57, 13 使用冒泡排序法将其排成一个从小到大的有 序数列。 思路-走代码, 你可以自己完整的分析冒泡的执行流程并可以不看老师代码也可以写出代码.
代码
public class BubbleSort {
//编写一个 main 方法 public static void main(String[] args) {
//老韩 化繁为简先死后活 // //
/*
数组 [24,69,80,57, 13] 第 1 轮排序: 目标把最大数放在最后 第 1 次比较[24,69,80,57, 13] 第 2 次比较[24,69,80,57, 13] 第 3 次比较[24,69,57,80, 13] 第 4 次比较[24,69,57, 13,80]
*/ int[] arr {24, 69, 80, 57, 13, - 1, 30, 200, - 110}; int temp 0; //用于辅助交换的变量
//将多轮排序使用外层循环包括起来即可 //先死后活 》 4 就是 arr.length - 1 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[j1]; arr[j1] temp; } } System.out.println(“\n第(i1)轮”); for(int j 0; j arr.length; j) { System.out.print(arr[j] “\t”);
} }
// for( int j 0; j 4;j) {//4 次比较 // //如果前面的数后面的数就交换 // if(arr[j] arr[j 1]) { // temp arr[j]; // arr[j] arr[j1]; // arr[j1] temp; // } // }
// System.out.println(“第 1 轮”); // for(int j 0; j arr.length; j) { // System.out.print(arr[j] “\t”); // } // /* // 第 2 轮排序: 目标把第二大数放在倒数第二位置 // 第 1 次比较[24,69,57, 13,80] // 第 2 次比较[24,57,69, 13,80] // 第 3 次比较[24,57, 13,69,80] // */
// for( int j 0; j 3;j) {//3 次比较 // //如果前面的数后面的数就交换
// if(arr[j] arr[j 1]) { // temp arr[j]; // arr[j] arr[j1]; // arr[j1] temp; // } // }
// System.out.println(“\n第 2 轮”); // for(int j 0; j arr.length; j) { // System.out.print(arr[j] “\t”); // }
// 第 3 轮排序: 目标把第 3 大数放在倒数第 3 位置 // 第 1 次比较[24,57, 13,69,80] // 第 2 次比较[24, 13,57,69,80]
// for( int j 0; j 2;j) {//2 次比较 // //如果前面的数后面的数就交换 // if(arr[j] arr[j 1]) { // temp arr[j]; // arr[j] arr[j1]; // arr[j1] temp; // } // }
// System.out.println(“\n第 3 轮”); // for(int j 0; j arr.length; j) { // System.out.print(arr[j] “\t”); // }
// /* // 第 4 轮排序: 目标把第 4 大数放在倒数第 4 位置 // 第 1 次比较[13,24,57,69,80] // */
// for( int j 0; j 1;j) {//1 次比较 // //如果前面的数后面的数就交换 // if(arr[j] arr[j 1]) { // temp arr[j]; // arr[j] arr[j1]; // arr[j1] temp; // } // }
// System.out.println(“\n第 4 轮”); // for(int j 0; j arr.length; j) { // System.out.print(arr[j] “\t”); // } }
} 12 查找 1 介绍 在java 中我们常用的查找有两种:
顺序查找 SeqSearch.java二分查找【二分法我们放在算法讲解】
12.2 案例演示
有一个数列 白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王猜数游戏从键盘中任意输入一个名称判断数列中是否 包含此名称【顺序查找】 要求: 如果找到了就提示找到并给出下标值。
import java.util.Scanner; public class SeqSearch {
//编写一个 main 方法 public static void main(String[] args) { /* 有一个数列 白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王猜数游戏 从键盘中任意输入一个名称判断数列中是否包含此名称【顺序查找】 要求: 如果找到了就提示找到并给出下标值
思路分析
定义一个字符串数组接收用户输入, 遍历数组逐一比较如果有则提示信息并退出 */
//定义一个字符串数组 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); }
} }
请对一个有序数组进行二分查找 { 1,8, 10, 89, 1000, 1234} 输入一个数看看该数组是否存在此数并且求出下标 如果没有就提示没有这个数。 13 多维数组-二维数组 多维数组我们只介绍二维数组。 二维数组的应用场景 比如我们开发一个五子棋游戏棋盘就是需要二维数组来表示。如图 14 二维数组的使用 1 快速入门案例 TwoDimensionalArray01.java 请用二维数组输出如下图形 0 0 0 0 0 0 0 0 1 0 0 0 0 2 0 3 0 0 0 0 0 0 0 0
代码
public class TwoDimensionalArray01 {
//编写一个 main 方法 public static void main(String[] args) {
/* 请用二维数组输出如下图形 0 0 0 0 0 0 0 0 1 0 0 0 0 2 0 3 0 0 0 0 0 0 0 0 */
//什么是二维数组 //老韩解读 //1. 从定义形式上看 int[][] //2. 可以这样理解原来的一维数组的每个元素是一维数组, 就构成二维数组 int[][] arr { {0, 0, 0, 0, 0, 0}, {0, 0, 1, 0, 0, 0}, {0,2, 0, 3, 0, 0}, {0, 0, 0, 0, 0, 0} };
//关于二维数组的关键概念 //(1)
System.out.println(“二维数组的元素个数” arr.length); //(2) 二维数组的每个元素是一维数组, 所以如果需要得到每个一维数组的值 // 还需要再次遍历 //(3) 如果我们要访问第 (i1)个一维数组的第j1 个值 arr[i][j]; // 举例 访问 3, 》 他是第 3 个一维数组的第 4 个值 arr[2][3] System.out.println(“第 3 个一维数组的第 4 个值” arr[2][3]); //3
//输出二维图形 for(int i 0; i arr.length; i) {//遍历二维数组的每个元素 //遍历二维数组的每个元素(数组) //老韩解读 //1. arr[i] 表示 二维数组的第 i1 个元素 比如 arr[0] 二维数组的第一个元素 //2. arr[i].length 得到 对应的 每个一维数组的长度 for(int j 0; j arr[i].length; j) { System.out.print(arr[i][j] ); //输出了一维数组 } System.out.println();//换行 } } } 6. 14.2 使用方式 1: 动态初始化
TwoDimensionalArray02.java 语法: 类型[][] 数组名new 类型[大小][大小] 比如: int a[][]new int[2][3] 使用演示 二维数组在内存的存在形式(!!画图) 代码
public class TwoDimensionalArray02 {
//编写一个 main 方法 public static void main(String[] args) {
//int arr[][] new int[2][3];
int arr[][]; //声明二维数组 arr new int[2][3];//再开空间
arr[ 1][1] 8; //遍历 arr 数组 for(int i 0; i arr.length; i) { for(int j 0;j arr[i].length; j) {//对每个一维数组遍历 System.out.print(arr[i][j] ); } System.out.println();//换行 } } }
14.3 使用方式 2: 动态初始化 先声明类型 数组名[][]; TwoDimensionalArray02.java 再定义(开辟空间) 数组名 new 类型[大小][大小] 赋值(有默认值比如int 类型的就是 0) 使用演示14.4 使用方式 3: 动态初始化-列数不确定
代码
public class TwoDimensionalArray03 {
//编写一个 main 方法 public static void main(String[] args) {
/* 看一个需求动态创建下面二维数组并输出
i 0: 1 i 1: 2 2 i 2: 3 3 3
一个有三个一维数组, 每个一维数组的元素是不一样的 */
//创建 二维数组一个有 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();//换行 }
} }
14.5 使用方式 4: 静态初始化 TwoDimensionalArray04.java 定义 类型 数组名[][] {{值 1,值 2…}, {值 1,值 2…}, {值 1,值 2…}} 使用即可 [ 固定方式访问 ]
比如: int[][] arr {{1, 1, 1}, {8,8,9}, { 100}}; 解读 定义了一个二维数组 arr arr 有三个元素(每个元素都是一维数组) 第一个一维数组有 3 个元素 , 第二个一维数组有 3 个元素, 第三个一维数组有 1 个元素 14.6 案例 TwoDimensionalArray05.java int arr[][]{{4,6}, { 1,4,5,7}, {-2}}; 遍历该二维数组并得到和
public class TwoDimensionalArray05 {
//编写一个 main 方法 public static void main(String[] args) {
/* int arr[][]{{4,6}, { 1,4,5,7}, {-2}}; 遍历该二维数组并得到和
思路
遍历二维数组并将各个值累计到 int sum */ int arr[][] {{4,6}, { 1,4,5,7}, {-2}}; int sum 0; for(int i 0; i arr.length; i) { //遍历每个一维数组 for(int j 0; j arr[i].length; j) { sum arr[i][j];
} } System.out.println(“sum” sum); } }
15 二维数组的应用案例
使用二维数组打印一个 10 行杨辉三角 YangHui.java
代码
public class YangHui {
//编写一个 main 方法 public static void main(String[] args) { /* 使用二维数组打印一个 10 行杨辉三角 1
1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1
规律 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[i1]; //给每个一维数组(行) 赋值 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();//换行. }
} }
16 二维数组使用细节和注意事项 一维数组的声明方式有: int[] x 或者 int x[] 二维数组的声明方式有: int[][] y 或者 int[] y [] 或者 int y [][] 二维数组实际上是由多个一维数组组成的它的各个一维数组的长度可以相同也可以不相同。比如 map[][] 是 一个二维数组 int map [][] {{1,2}, {3,4,5}} 由 map[0] 是一个含有两个元素的一维数组 map[ 1] 是一个含有三个元素的一维数组构成我们也称为列数不等 的二维数组 17 二维数组课堂练习 18 本章作业
4 题的分析示意图:
第 7 章 面向对象编程(基础部分) 7. 1 类与对象 7. 1. 1看一个养猫猫问题 张老太养了两只猫猫:一只名字叫小白,今年 3 岁, 白色。还有一只叫小花,今年 100 岁,花色。请编写一个程序当用户 输入小猫的名字时就显示该猫的名字年龄颜色。如果用户输入的小猫名错误则显示 张老太没有这只猫猫。 7. 1.2使用现有技术解决 Object01.java
单独的定义变量解决使用数组解决
1.3现有技术解决的缺点分析 不利于数据的管理 效率低》 引出我们的新知识点 类与对象 哲学, 道家思想 java 设计者 引入 类与对象(OOP) 根本原因就是现有的技术不能完美的解决新的新的需求. 代码
public class Object01 {
//编写一个 main 方法 public static void main(String[] args) {
/* 张老太养了两只猫猫:一只名字叫小白,今年 3 岁, 白色。 还有一只叫小花,今年 100 岁,花色。请编写一个程序当用户输入小猫的名字时 就显示该猫的名字年龄颜色。如果用户输入的小猫名错误 则显示 张老太没有这只猫猫。
*/ //单独变量来解决 不利于数据的管理(你把一只猫的信息拆解) //第 1 只猫信息
// String cat 1Name “小白”; // int cat 1Age 3; // String cat 1Color “白色”;
// //第 2 只猫信息 // String cat2Name “小花”; // int cat2Age 100; // String cat2Color “花色”;
//数组 (1)数据类型体现不出来(2) 只能通过[下标]获取信息造成变量名字和内容 // 的对应关系不明确(3) 不能体现猫的行为 //第 1 只猫信息
// String[] cat 1 {“小白”, “3”, “白色”}; // String[] cat2 {“小花”, “100”, “花色”};
//使用OOP 面向对象解决 //实例化一只猫[创建一只猫对象] //老韩解读 //1. new Cat() 创建一只猫(猫对象) //2. Cat cat 1 new Cat(); 把创建的猫赋给 cat 1
//3. cat 1 就是一个对象 Cat cat 1 new Cat(); cat1.name “小白”; cat 1.age 3; cat 1.color “白色”; cat 1.weight 10; //创建了第二只猫并赋给 cat2 //cat2 也是一个对象(猫对象) Cat cat2 new Cat(); cat2.name “小花”; cat2.age 100; cat2.color “花色”; cat2.weight 20;
//怎么访问对象的属性呢 System.out.println(“第 1 只猫信息” cat 1.name cat 1.age cat 1.color cat 1.weight);
System.out.println(“第 2 只猫信息” cat2.name cat2.age cat2.color cat2.weight); } }
//使用面向对象的方式来解决养猫问题 //
//定义一个猫类 Cat - 自定义的数据类型 class Cat { //属性/成员变量 String name; //名字 int age; //年龄 String color; //颜色 //double weight; //体重
//行为 } 1.4 一个程序就是一个世界有很多事物(对象[属性, 行为]) 1.5类与对象的关系示意图 1.6类与对象的关系示意图 1.7快速入门-面向对象的方式解决养猫问题 Object01.java - 看前面的代码 1.8类和对象的区别和联系
通过上面的案例和讲解我们可以看出:
类是抽象的概念的代表一类事物, 比如人类,猫类…, 即它是数据类型.对象是具体的实际的代表一个具体事物, 即 是实例.类是对象的模板对象是类的一个个体对应一个实例 1.9对象在内存中存在形式(重要的)必须搞清楚。 10 属性/成员变量/字段 基本介绍
从概念或叫法上看 成员变量 属性 field(字段) (即 成员变量是用来表示属性的授课中统一叫 属性) 案例演示Car(name,price,color) Object02.java
public class Object02 {
//编写一个 main 方法 public static void main(String[] args) { } }
class Car { String name;//属性, 成员变量, 字段 field double price; String color; String[] master;//属性可以是基本数据类型也可以是引用类型(对象数组) }
属性是类的一个组成部分一般是基本数据类型,也可是引用类型(对象数组)。比如我们前面定义猫类 的 int age 就 是属性 注意事项和细节说明 PropertiesDetail.java属性的定义语法同变量示例访问修饰符 属性类型 属性名; 这里老师简单的介绍访问修饰符 控制属性的访问范围 有四种访问修饰符 public, proctected, 默认, private ,后面我会详细介绍属性的定义类型可以为任意类型包含基本类型或引用类型属性如果不赋值有默认值规则和数组一致。具体说: int 0short 0, byte 0, long 0, float 0.0,double 0.0char \u0000 boolean false String null 案例演示[Person 类] 代码
public class PropertiesDetail {
//编写一个 main 方法 public static void main(String[] args) { //创建 Person 对象 //p1 是对象名(对象引用) //new Person() 创建的对象空间(数据) 才是真正的对象 Person p1 new Person();
//对象的属性默认值遵守数组规则: //int 0 short 0, byte 0, long 0, float 0.0,double 0.0 char \u0000 boolean false String null
System.out.println(“\n 当前这个人的信息”); System.out.println(“age” p1.age name
p1.name sal p1.sal isPass p1.isPass) ; } }
class Person { //四个属性 int age; String name; double sal; boolean isPass; } 11 如何创建对象
先声明再创建 Cat cat ; //声明对象 cat cat new Cat(); //创建直接创建 Cat cat new Cat(); 12 如何访问属性 基本语法 对象名.属性名; 案例演示赋值和输出 cat.name ; cat.age; cat.color; 类和对象的内存分配机制(重要) 看一个思考题 我们定义一个人类(Person)(包括 名字,年龄) 。 (Object03.java) 13 类和对象的内存分配机制 Java 内存的结构分析
栈 一般存放基本数据类型(局部变量)堆 存放对象(Cat cat , 数组等)方法区常量池(常量比如字符串) 类加载信息示意图 [Cat (name, age, price)] Java 创建对象的流程简单分析
Person p new Person(); p.name “jack”; p.age 10 先加载 Person类信息(属性和方法信息, 只会加载一次) 在堆中分配空间, 进行默认初始化(看规则) 把地址赋给 p , p 就指向对象 进行指定初始化 比如 p.name ”jack” p.age 10
看一个练习题并分析画出内存布局图进行分析
7.2 成员方法 7.2. 1基本介绍
在某些情况下我们要需要定义成员方法(简称方法) 。比如人类: 除了有一些属性外( 年龄姓名…),我们人类还有一 些行为比如:可以说话、跑步…,通过学习还可以做算术题。这时就要用成员方法才能完成。现在要求对 Person类完善。 7.2.2成员方法快速入门 Method01.java
添加 speak 成员方法,输出 “我是一个好人”添加 cal01 成员方法,可以计算从 1… 1000 的结果添加 cal02 成员方法,该方法可以接收一个数 n 计算从 1…n 的结果添加 getSum 成员方法,可以计算两个数的和 代码
public class Method01 {
//编写一个 main 方法 public static void main(String[] args) { //方法使用 //1. 方法写好后如果不去调用(使用) 不会输出 //2. 先创建对象 ,然后调用方法即可 Person p1 new Person(); p1.speak(); //调用方法 p1.cal01(); //调用 cal01 方法 p1.cal02(5); //调用 cal02 方法同时给 n 5 p1.cal02(10); //调用 cal02 方法同时给 n 10
//调用 getSum 方法同时 num1 10, num220
//把 方法 getSum 返回的值赋给 变量 returnRes int returnRes p1.getSum( 10, 20); System.out.println(“getSum 方法返回的值” returnRes); } }
class Person {
String name; int age; //方法(成员方法) //添加 speak 成员方法,输出 “我是一个好人” //老韩解读 //1. public 表示方法是公开 //2. void 表示方法没有返回值 //3. speak() : speak 是方法名 () 形参列表 //4. {} 方法体可以写我们要执行的代码 //5. System.out.println(“我是一个好人”); 表示我们的方法就是输出一句话
public void speak() { System.out.println(“我是一个好人”); }
//添加 cal01 成员方法,可以计算从 1… 1000 的结果 public void cal01() { //循环完成
int res 0; for(int i 1; i 1000; i) { res i; } System.out.println(“cal01 方法 计算结果” res); } //添加 cal02 成员方法,该方法可以接收一个数 n 计算从 1…n 的结果 //老韩解读 //1. (int n) 形参列表 表示当前有一个形参 n, 可以接收用户输入 public void cal02(int n) { //循环完成 int res 0; for(int i 1; i n; i) { res i; } System.out.println(“cal02 方法 计算结果” res); }
//添加 getSum 成员方法,可以计算两个数的和 //老韩解读 //1. public 表示方法是公开的 //2. int :表示方法执行后返回一个 int 值 //3. getSum 方法名 //4. (int num1, int num2) 形参列表2 个形参可以接收用户传入的两个数 //5. return res; 表示把 res 的值 返回 public int getSum(int num1, int num2) {
int res num1 num2; return res; } }
7.2.3方法的调用机制原理(重要!-示意图!!!) 提示画出程序执行过程[getSum]说明
7.2.4为什么需要成员方法 Method02.java 看一个需求 请遍历一个数组 , 输出数组的各个元素值。 解决思路 1 传统的方法就是使用单个 for 循环将数组输出大家看看问题是什么
解决思路 2: 定义一个类 MyTools ,然后写一个成员方法调用方法实现,看看效果又如何。 代码
public class Method02 {
//编写一个 main 方法 public static void main(String[] args) {
//请遍历一个数组 , 输出数组的各个元素值 int [][] map {{0,0, 1}, { 1, 1, 1}, { 1, 1,3}};
//使用方法完成输出, 创建 MyTools 对象 MyTools tool new MyTools();
//遍历map 数组 //传统的解决方式就是直接遍历 // for(int i 0; i map.length; i) { // for(int j 0; j map[i].length; j) { // System.out.print(map[i][j] “\t”); // } // System.out.println(); // } //使用方法 tool.printArr(map); //…
// //要求再次遍历map 数组 // for(int i 0; i map.length; i) { // for(int j 0; j map[i].length; j) { // System.out.print(map[i][j] “\t”); // } // System.out.println(); // } tool.printArr(map);
//…再次遍历 // // for(int i 0; i map.length; i) { // for(int j 0; j map[i].length; j) { // System.out.print(map[i][j] “\t”); // } // System.out.println(); // } tool.printArr(map);
} }
//把输出的功能写到一个类的方法中,然后调用该方法即可 class MyTools {
//方法接收一个二维数组
public void printArr(int[][] map) { System.out.println(“”); //对传入的map 数组进行遍历输出 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(); } } }
7.2.5成员方法的好处
提高代码的复用性可以将实现的细节封装起来然后供其他用户来调用即可 7.2.6成员方法的定义
访问修饰符 返回数据类型 方法名 (形参列表… ) {//方法体 语句 return 返回值; } 形参列表表示成员方法输入 cal(int n) getSum(int num1, int num2) 返回数据类型表示成员方法输出, void 表示没有返回值 方法主体表示为了实现某一功能代码块 return 语句不是必须的。 老韩提示: 结合前面的题示意图, 来理解 7.2.7注意事项和使用细节 MethodDetail.java
public class MethodDetail {
public static void main(String[] args) {
AA a new AA(); int[] res a.getSumAndSub(1, 4); System.out.println(“和” res[0]); System.out.println(“差” res[ 1]);
//细节: 调用带参数的方法时一定对应着参数列表传入相同类型或兼容类型 的参数 byte b 1 1; byte b2 2; a.getSumAndSub(b1, b2);//byte - int //a.getSumAndSub(1. 1, 1.8);//double -int(×) //细节: 实参和形参的类型要一致或兼容、个数、顺序必须一致
//a.getSumAndSub(100);//× 个数不一致 a.f3(“tom”, 10); //ok //a.f3( 100, “jack”); // 实际参数和形式参数顺序不对
} }
class AA {
//细节: 方法不能嵌套定义 public void f4() { //错误 // public void f5() {
// } }
public void f3(String str, int n) { }
//1. 一个方法最多有一个返回值 [思考如何返回多个结果 返回数组 ] public int[] getSumAndSub(int n1, int n2) {
int[] resArr new int[2]; // resArr[0] n1 n2;
resArr[ 1] n1 - n2; return resArr; } //2. 返回类型可以为任意类型包含基本类型或引用类型(数组对象) // 具体看 getSumAndSub //
//3. 如果方法要求有返回数据类型则方法体中最后的执行语句必须为 return 值; // 而且要求返回值类型必须和 return 的值类型一致或兼容 public double f1() {
double d 1 1. 1 * 3; int n 100; return n; // int -double //return d 1; //ok? double - int }
//如果方法是 void 则方法体中可以没有 return 语句或者 只写 return ; //老韩提示在实际工作中我们的方法都是为了完成某个功能所以方法名要有一定含义 // 最好是见名知意 public void f2() {
System.out.println(“hello1”); System.out.println(“hello1”); System.out.println(“hello1”); int n 10;
//return ; }
}
访问修饰符 (作用是控制 方法使用的范围) 如果不写默认访问[有四种: public, protected, 默认, private], 具体在后面说
返回数据类型
一个方法最多有一个返回值 [思考如何返回多个结果 返回数组 ]返回类型可以为任意类型包含基本类型或引用类型(数组对象)如果方法要求有返回数据类型则方法体中最后的执行语句必须为 return 值; 而且要求返回值类型必须和 return 的 值类型一致或兼容如果方法是 void 则方法体中可以没有 return 语句或者 只写 return ; 方法名 遵循驼峰命名法最好见名知义表达出该功能的意思即可, 比如 得到两个数的和 getSum, 开发中按照规范
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.2.8类定义的完善
7.2.9课堂练习题 MethodExercise01.java
编写类 AA 有一个方法判断一个数是奇数 odd 还是偶数, 返回boolean根据行、列、字符打印 对应行数和列数的字符比如行4 列4 字符#,则打印相应的效果 老师建议一定要自己写一遍不要嫌太简单. 代码
public class MethodExercise01 {
//编写一个 main 方法 public static void main(String[] args) {
AA a new AA(); // if(a.isOdd(2)) {//T , 这样的写法以后会看到很多 // System.out.println(“是奇数”); // } else { // System.out.println(“是偶数”); // } //
// // 使用 print 方法 a.print(4, 4, ‘#’);
} } //编写类 AA 有一个方法判断一个数是奇数 odd 还是偶数, 返回boolean class AA { //思路 //1. 方法的返回类型 boolean //2. 方法的名字 isOdd //3. 方法的形参 (int num) //4. 方法体 , 判断
public boolean isOdd(int num) { // if(num % 2 ! 0) { // return true; // } else { // return false; // }
//return num % 2 ! 0 ? true; false; // return num % 2 ! 0;
}
//根据行、列、字符打印 对应行数和列数的字符 //比如行4 列4 字符#,则打印相应的效果 /* */ //思路 //1. 方法的返回类型 void //2. 方法的名字 print //3. 方法的形参 (int row, int col, char c) //4. 方法体 , 循环 public void print(int row, int col, char c) { for(int i 0; i row; i) { for(int j 0;j col; j) {//输出每一行 System.out.print©; } System.out.println(); //换行 } } } 7.3 成员方法传参机制(非常非常重要)
方法的传参机制对我们今后的编程非常重要一定要搞的清清楚楚明明白白。我们通过案例来学习 7.3. 1基本数据类型的传参机制
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 b20 } }
class AA { public void swap(int a,int b){ System.out.println(“\na 和 b 交换前的值\na” a “\tb” b);//a 10 b20 //完成了 a 和 b 的交换 int tmp a; a b; b tmp; System.out.println(“\na 和 b 交换后的值\na” a “\tb” b);//a20 b10 } }
7.3.2引用数据类型的传参机制
看一个案例 MethodParameter02.java B 类中编写一个方法test 100 可以接收一个数组在方法中修改该数组看看原来的数组是否变化会变化 B 类中编写一个方法test200 可以接收一个 Person(age,sal)对象在方法中修改该对象属性看看原来的对象是否变
化会变化.
public class MethodParameter02 { //编写一个 main 方法 public static void main(String[] args) { //测试 B b new B(); // int[] arr { 1, 2, 3}; // b.test 100(arr);//调用方法 // System.out.println( main 的 arr 数组 ); // //遍历数组 // for(int i 0; i arr.length; i) { // System.out.print(arr[i] “\t”); // } // System.out.println();
//测试 Person p new Person(); p.name “jack”; p.age 10; b.test200§; //测试题, 如果 test200 执行的是 p null ,下面的结果是 10 //测试题, 如果 test200 执行的是 p new Person();…, 下面输出的是 10 System.out.println(“main 的 p.age” p.age);//10000 } }
class Person { String name; int age; } class B { public void test200(Person p) { //p.age 10000; //修改对象属性 //思考 p new Person(); p.name “tom”; p.age 99; //思考 //p null; }
//B 类中编写一个方法 test 100 //可以接收一个数组在方法中修改该数组看看原来的数组是否变化 public void test 100(int[] arr) { arr[0] 200;//修改元素 //遍历数组 System.out.println( test 100 的 arr 数组 ); for(int i 0; i arr.length; i) { System.out.print(arr[i] “\t”); } System.out.println(); }
} 结论及示意图 引用类型传递的是地址 (传递也是值但是值是地址) 可以通过形参影响实参 在看一个案例下面的方法会对原来的对象有影响吗 pnull 和 p new Person(); 对应示意图
7.3.3成员方法返回类型是引用类型应用实例 MethodExercise02.java
编写类 MyTools 类编写一个方法可以打印二维数组的数据。编写一个方法 copyPerson 可以复制一个 Person 对象返回复制的对象。克隆对象 注意要求得到新对象和原来的 对象是两个独立的对象只是他们的属性相同 代码
public class MethodExercise02 {
//编写一个 main 方法 public static void main(String[] args) {
Person p new Person(); p.name “milan”; p.age 100; //创建 tools MyTools tools new MyTools(); Person p2 tools.copyPerson§;
//到此 p 和 p2 是 Person对象但是是两个独立的对象属性相同 System.out.println(“p 的属性 age” p.age 名字 p.name); System.out.println(“p2 的属性 age” p2.age 名字 p2.name); //这里老师提示 可以同 对象比较看看是否为同一个对象 System.out.println(p p2);//false
} }
class Person { String name; int age; }
class MyTools {
//编写一个方法 copyPerson 可以复制一个 Person 对象返回复制的对象。克隆对象 //注意要求得到新对象和原来的对象是两个独立的对象只是他们的属性相同 // //编写方法的思路 //1. 方法的返回类型 Person //2. 方法的名字 copyPerson //3. 方法的形参 (Person p) //4. 方法体, 创建一个新对象并复制属性返回即可
public Person copyPerson(Person p) { //创建一个新的对象 Person p2 new Person(); p2.name p.name; //把原来对象的名字赋给 p2.name p2.age p.age; //把原来对象的年龄赋给 p2.age return p2; } }
7.4 方法递归调用(非常非常重要比较难) 7.4. 1基本介绍 简单的说: 递归就是方法自己调用自己,每次调用时传入不同的变量.递归有助于编程者解决复杂问题, 同时可以让代码变 得简洁 7.4.2递归能解决什么问题?
7.4.3递归举例
列举两个小案例,来帮助大家理解递归调用机制
打印问题阶乘问题 代码
public class Recursion01 {
//编写一个 main 方法 public static void main(String[] args) {
T t 1 new T(); t 1.test(4);//输出什么 n2 n3 n4 int res t1.factorial(5); System.out.println(“5 的阶乘 res ” res); } }
class T { //分析 public void test(int n) { if (n 2) { test(n - 1); } System.out.println(“n” n); }
//factorial 阶乘 public int factorial(int n) { if (n 1) { return 1; } else { return factorial(n - 1) * n; } }
}
7.4.4递归重要规则
7.4.5课堂练习 RecursionExercise01.java
代码
public class RecursionExercise01 {
//编写一个 main 方法 public static void main(String[] args) {
T t 1 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 求出它的值是多 思路分析
当 n 1 斐波那契数 是 1当 n 2 斐波那契数 是 1当 n 3 斐波那契数 是前两个数的和这里就是一个递归的思路 */
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(“要求输入的 n1 的整数”); return - 1; } }
/* 猴子吃桃子问题有一堆桃子猴子第一天吃了其中的一半并再多吃了一个 以后每天猴子都吃其中的一半然后再多吃一个。当到第 10 天时 想再吃时 (即还没吃) 发现只有 1 个桃子了。问题最初共多少个桃子
思路分析 逆推
day 10 时 有 1 个桃子day 9 时 有 (day10 1) * 2 4day 8 时 有 (day9 1) * 2 10规律就是 前一天的桃子 (后一天的桃子 1) *2//就是我们的能力递归 */ 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递归调用应用实例-迷宫问题 MiGong.java
代码
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; //测试回溯 // map[2][1] 1; // map[2][2] 1; // map[ 1][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 t 1 new T(); //下右上左 t 1.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; } }
}
//修改找路策略看看路径是否有变化 //下-右-上-左 上-右-下-左 public boolean findWay2(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(findWay2(map, i - 1, j)) {//先走上 return true; } else if(findWay2(map, i, j 1)){//右 return true; } else if(findWay2(map, i1, j)) {//下 return true; } else if(findWay2(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递归调用应用实例-汉诺塔
汉诺塔传说 汉诺塔汉诺塔 (又称河内塔) 问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子 在一根柱子上从下往上按照大小顺序摞着 64 片圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一 根柱子上。并且规定在小圆盘上不能放大圆盘在三根柱子之间一次只能移动一个圆盘。
假如每秒钟移动一次共需多长时间呢移完这些金片需要 5845.54 亿年以上太阳系的预期寿命据说也就是数百亿年。 真的过了 5845.54 亿年地球上的一切生命连同梵塔、庙宇等都早已经灰飞烟灭 汉诺塔代码实现 看老师代码演示 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递归调用应用实例-八皇后问题[同学们先尝试做后面老师评讲.] 八皇后问题说明 八皇后问题是一个古老而著名的问题是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯 · 贝瑟尔于 1848 年 提出在 8×8 格的国际象棋上摆放八个皇后使其不能互相攻击即任意两个皇后都不能处于同一行、同一列或同 一斜线上问有多少种摆法。
7.5 方法重载(OverLoad) 7.5. 1基本介绍 java 中允许同一个类中多个同名方法的存在但要求 形参列表不一致 比如System.out.println(); out 是 PrintStream 类型 OverLoad01.java 7.5.2重载的好处
减轻了起名的麻烦减轻了记名的麻烦 7.5.3快速入门案例 OverLoad01.java 案例类MyCalculator 方法calculatecalculate(int n1, int n2) //两个整数的和calculate(int n1, double n2) //一个整数一个 double 的和calculate(double n2, int n1)//一个 double ,一个 Int 和calculate(int n1, int n2,int n3)//三个 int 的和
代码
public class OverLoad01 {
//编写一个 main 方法 public static void main(String[] args) {
// System.out.println( 100); // System.out.println(“hello,world”); // System.out.println(‘h’); // System.out.println( 1. 1); // System.out.println(true); // MyCalculator mc new MyCalculator(); System.out.println(mc.calculate( 1, 2)); System.out.println(mc.calculate( 1. 1, 2)); System.out.println(mc.calculate( 1, 2. 1)); } }
class MyCalculator {
//下面的四个 calculate 方法构成了重载 //两个整数的和 public int calculate(int n1, int n2) { System.out.println(“calculate(int n1, int n2) 被调用”);
return n1 n2; }
//没有构成方法重载, 仍然是错误的因为是方法的重复定义 // public void calculate(int n1, int n2) { // System.out.println(“calculate(int n1, int n2) 被调用”); // int res n1 n2; // }
//看看下面是否构成重载, 没有构成而是方法的重复定义,就错了 // public int calculate(int a1, int a2) { // System.out.println(“calculate(int n1, int n2) 被调用”); // return a1 a2; // }
//一个整数一个 double 的和 public double calculate(int n1, double n2) { return n1 n2; } //一个 double ,一个 Int 和 public double calculate(double n1, int n2) { System.out.println(“calculate(double n1, int n2) 被调用…”); return n1 n2; } //三个 int 的和 public int calculate(int n1, int n2,int n3) {
return n1 n2 n2; }
}
7.5.4注意事项和使用细节
7.5.5课堂练习题
public class OverLoadExercise {
//编写一个 main 方法 public static void main(String[] args) {
//在主类的 main ()方法中分别用参数区别调用三个方法 Methods method new Methods(); method.m( 10);//100 method.m( 10, 20);//200 method.m(“韩顺平教育 hello”);//字符串信息
//测试 System.out.println(method.max( 10, 24)); // 24 System.out.println(method.max( 10.0, 21.4)); // 21.4 System.out.println(method.max( 10.0, 1.4, 30.0)); // 30.0 } }
/* 编写程序类 Methods 中定义三个重载方法并调用。方法名为 m。 三个方法分别接收一个 int 参数、两个 int 参数、一个字符串参数。分别执行平方运算并输出结果 相乘并输出结果输出字符串信息。在主类的 main ()方法中分别用参数区别调用三个方法
定义三个重载方法 max() 第一个方法返回两个 int 值中的最大值 第二个方法返回两个 double 值中的最大值第三个方法
返回三个 double 值中的最大值并分别调用三个方法 */ class Methods {
//分析 //1 方法名 max //2 形参 (int,int) //3.int public int max(int n1, int n2) { return n1 n2 ? n1 : n2; }
//分析 //1 方法名 max //2 形参 (double,double) //3.double public double max(double n1, double n2) { return n1 n2 ? n1 : n2; }
//分析 //1 方法名 max //2 形参 (double,double,double) //3.double public double max(double n1, double n2, double n3) {
System.out.println(“max(double n1, double n2, double n3)”); //求出 n1 和 n2 的最大值 double max1 n1 n2 ? n1 : n2; return max1 n3 ? max1 : n3; }
public double max(double n1, double n2, int n3) {
System.out.println(“max(double n1, double n2, int n3)”); //求出 n1 和 n2 的最大值 double max1 n1 n2 ? n1 : n2; return max1 n3 ? max1 : n3; }
//分析 //1 方法名 m //2 形参 (int) //3.void public void m(int n) { System.out.println(“平方” (n * n)); }
//1 方法名 m //2 形参 (int, int) //3.void
public void m(int n1, int n2) { System.out.println(“相乘” (n1 * n2)); }
//1 方法名 m //2 形参 (String) //3.void public void m(String str) { System.out.println(“传入的 str” str); } } 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 。。 //可以使用方法重载 // public int sum(int n1, int n2) {//2 个数的和 // return n1 n2; // } // public int sum(int n1, int n2, int n3) {//3 个数的和 // return n1 n2 n3; // } // public int sum(int n1, int n2, int n3, int n4) {//4 个数的和 // return n1 n2 n3 n4; // } //… //上面的三个方法名称相同功能相同, 参数个数不同- 使用可变参数优化 //老韩解读
//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 t 1 new T(); t 1.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.6.5课堂练习
public class VarParameterExercise {
//编写一个 main 方法 public static void main(String[] args) { HspMethod hm new HspMethod(); System.out.println(hm.showScore(“milan” , 90. 1, 80.0 )); System.out.println(hm.showScore(“terry” , 90. 1, 80.0, 10,30.5,70 )); } }
class HspMethod {
/* 有三个方法分别实现返回姓名和两门课成绩(总分) 返回姓名和三门课成绩(总分) 返回姓名和五门课成绩 (总分) 。 封装成一个可变参数的方法 */
//分析 1. 方法名 showScore 2. 形参(String ,double… ) 3. 返回 String //听课小伙伴老师要求必须自己动手写 public String showScore(String name ,double… scores ) {
double totalScore 0; for(int i 0; i scores.length; i) { totalScore scores[i]; } return name 有 scores.length “门课的成绩总分为” totalScore; } } 7.7 作用域 7.7. 1基本使用
public class VarScope {
//编写一个 main 方法 public static void main(String[] args) { } }
class Cat { //全局变量也就是属性作用域为整个类体 Cat 类cry eat 等方法使用属性 //属性在定义时可以直接赋值 int age 10; //指定的值是 10
//全局变量(属性)可以不赋值直接使用因为有默认值 double weight; //默认值是 0.0
public void hi() { //局部变量必须赋值后才能使用因为没有默认值 int num 1; String address “北京的猫”; System.out.println(“num” num); System.out.println(“address” address); System.out.println(“weight” weight);//属性 }
public void cry() { //1. 局部变量一般是指在成员方法中定义的变量 //2. n 和 name 就是局部变量 //3. n 和 name 的作用域在 cry 方法中 int n 10; String name “jack”; System.out.println(“在 cry 中使用属性 age” age); }
public void eat() {
System.out.println(“在 eat 中使用属性 age” age);
//System.out.println(“在 eat 中使用 cry 的变量 name” name);//错误 } } 7.7.2注意事项和细节使用
public class VarScopeDetail {
//编写一个 main 方法 public static void main(String[] args) { Person p1 new Person(); /* 属性生命周期较长伴随着对象的创建而创建伴随着对象的销毁而销毁。 局部变量生命周期较短伴随着它的代码块的执行而创建 伴随着代码块的结束而销毁。即在一次方法调用过程中 */ //p1.say();//当执行 say 方法时say 方法的局部变量比如 name,会创建当 say 执行完毕后 //name 局部变量就销毁,但是属性(全局变量)仍然可以使用 // T t 1 new T(); t 1.test(); //第 1 种跨类访问对象属性的方式 t 1.test2(p1);//第 2 种跨类访问对象属性的方式
} }
class T {
//全局变量/属性可以被本类使用或其他类使用 (通过对象调用) public void test() { Person p1 new Person(); System.out.println(p1.name);//jack }
public void test2(Person p) { System.out.println(p.name);//jack } }
class Person { //细节: 属性可以加修饰符(public protected private…) // 局部变量不能加修饰符 public int age 20; String name “jack”;
public void say() { //细节 属性和局部变量可以重名访问时遵循就近原则 String name “king”; System.out.println(“say() name” name); }
public void hi() { String address “北京”; //String address “上海”;//错误,重复定义变量 String name “hsp”;//可以 } } 7.8 构造方法/构造器
7.8. 1看一个需求 我们来看一个需求前面我们在创建人类的对象时是先把一个对象创建好后再给他的年龄和姓名属性赋值如 果现在我要求在创建人类的对象时就直接指定这个对象的年龄和姓名该怎么做? 这时就可以使用构造器。 7.8.2基本语法 [修饰符] 方法名(形参列表){ 方法体; } 老韩说明 构造器的修饰符可以默认 也可以是 public protected private 构造器没有返回值 方法名 和类名字必须一样 参数列表 和 成员方法一样的规则 构造器的调用, 由系统完成 7.8.3基本介绍 构造方法又叫构造器(constructor) 是类的一种特殊的方法它的主要作用是完成对新对象的初始化。它有几个特点 方法名和类名相同 没有返回值 在创建对象时系统会自动的调用该类的构造器完成对象的初始化。 7.8.4快速入门 现在我们就用构造方法来完成刚才提出的问题: 在创建人类的对象时 就直接指定这个对象的年龄和姓名 Constructor01.java
public class Constructor01 {
//编写一个 main 方法 public static void main(String[] args) { //当我们 new 一个对象时直接通过构造器指定名字和年龄 Person p1 new Person(“smith”, 80); System.out.println(“p1 的信息如下”); System.out.println(“p1 对象 name” p1.name);//smith System.out.println(“p1 对象 age” p1.age);//80 } }
//在创建人类的对象时就直接指定这个对象的年龄和姓名 // class Person { String name; int age; //构造器 //老韩解读 //1. 构造器没有返回值, 也不能写 void //2. 构造器的名称和类 Person 一样 //3. (String pName, int pAge) 是构造器形参列表规则和成员方法一样 public Person(String pName, int pAge) { System.out.println(“构造器被调用~~ 完成对象的属性初始化”); name pName; age pAge; }
}
7.8.5注意事项和使用细节
public class ConstructorDetail {
//编写一个 main 方法 public static void main(String[] args) { Person p1 new Person(“king”, 40);//第 1 个构造器 Person p2 new Person(“tom”);//第 2 个构造器 Dog dog1 new Dog();//使用的是默认的无参构造器
} } class Dog { //如果程序员没有定义构造器系统会自动给类生成一个默认无参构造器(也叫默认构造器) //使用javap 指令 反编译看看 /* 默认构造器 Dog() {
} */ //一旦定义了自己的构造器,默认的构造器就覆盖了就不能再使用默认的无参构造器 //除非显式的定义一下, 即: Dog(){} 写 (这点很重要) // public Dog(String dName) { //… } Dog() { //显式的定义一下 无参构造器
} }
class Person { String name; int age;//默认 0 //第 1 个构造器
public Person(String pName, int pAge) { name pName; age pAge; } //第 2 个构造器, 只指定人名不需要指定年龄 public Person(String pName) { name pName; } } 7.8.6课堂练习题 ConstructorExercise.java 在前面定义的 Person类中添加两个构造器 第一个无参构造器利用构造器设置所有人的 age 属性初始值都为 18
第二个带 pName和 pAge 两个参数的构造器使得每次创建 Person对象的同时初始化对象的 age 属性值和 name 属性值。 分别使用不同的构造器创建对象. 代码:
public class ConstructorExercise {
//编写一个 main 方法 public static void main(String[] args) { Person p1 new Person();//无参构造器
//下面输出 name null, age 18
System.out.println(“p1 的信息 name” p1.name age p1.age);
Person p2 new Person(“scott”, 50); //下面输出 name scott, age 50 System.out.println(“p2 的信息 name” p2.name age p2.age);
} }
/**
在前面定义的 Person类中添加两个构造器:第一个无参构造器利用构造器设置所有人的 age 属性初始值都为 18第二个带 pName 和 pAge 两个参数的构造器使得每次创建 Person对象的同时初始化对象的 age 属性值和 name 属性值。分别使用不同的构造器创建对象. */
class Person { String name;//默认值 null int age;//默认 0 //第一个无参构造器利用构造器设置所有人的 age 属性初始值都为 18 public Person() { age 18;// } //第二个带 pName 和 pAge 两个参数的构造器 public Person(String pName, int pAge) {
name pName; age pAge; } } 7.9 对象创建的流程分析 7.9. 1看一个案例
学习完构造器后,我们类的定义就应该更加完善了
10 this 关键字 1 先看一段代码,并分析问题
代码:
public class This01 {
//编写一个 main 方法
public static void main(String[] args) {
Dog dog1 new Dog(“大壮”, 3); System.out.println(“dog1 的 hashcode” dog1.hashCode()); //dog1 调用了 info()方法 dog1.info();
System.out.println(“”); Dog dog2 new Dog(“大黄”, 2); System.out.println(“dog2 的 hashcode” dog2.hashCode()); dog2.info(); } }
class Dog{ //类
String name; int age; // public Dog(String dName, int dAge){//构造器 // name dName; // age dAge; // } //如果我们构造器的形参能够直接写成属性名就更好了 //但是出现了一个问题根据变量的作用域原则 //构造器的 name 是局部变量而不是属性 //构造器的 age 是局部变量而不是属性
// 引出 this 关键字来解决 public Dog(String name, int age){//构造器 //this.name 就是当前对象的属性 name this.name name; //this.age 就是当前对象的属性 age this.age age; System.out.println(“this.hashCode” this.hashCode()); }
public void info(){//成员方法,输出属性 x 信息 System.out.println(“this.hashCode” this.hashCode()); System.out.println(name “\t” age “\t”); } } 10.2 深入理解 this 为了进一步理解 this,我们再看一个案例 (This01.java) 10.3 this 的注意事项和使用细节 ThisDetail.java this 关键字可以用来访问本类的属性、方法、构造器 this 用于区分当前类的属性和局部变量 访问成员方法的语法this.方法名(参数列表); 访问构造器语法this(参数列表); 注意只能在构造器中使用(即只能在构造器中访问另外一个构造器, 必须放在第一 条语句) this 不能在类定义的外部使用只能在类定义的方法中使用。
10.4 this 的课堂案例 TestPerson.java 定义 Person类里面有 name、age 属性并提供compareTo 比较方法用于判断是否和另一个人相等提供测试类 TestPerson 用于测试, 名字和年龄完全一样就返回true, 否则返回 false 代码
public class TestPerson {
//编写一个 main 方法 public static void main(String[] args) {
Person p1 new Person(“mary”, 20); Person p2 new Person(“mary”, 20);
System.out.println(“p1 和 p2 比较的结果” p1.compareTo(p2)); } }
/* 定义 Person 类里面有 name 、age 属性并提供 compareTo 比较方法 用于判断是否和另一个人相等提供测试类 TestPerson 用于测试, 名字和年龄完全一样就返回true, 否则返回 false
*/ class Person { String name; int age; //构造器 public Person(String name, int age) { this.name name; this.age age; } //compareTo 比较方法 public boolean compareTo(Person p) { //名字和年龄完全一样 // if(this.name.equals(p.name) this.age p.age) { // return true; // } else { // return false; // } return this.name.equals(p.name) this.age p.age; } } 7. 11 本章作业
眼高手低-千万不要这样.-零基础
第 8 章 面向对象编程(中级部分) 8. 1 IDE (集成开发环境) -IDEA 8. 1. 1IDEA 介绍
IDEA 全称 IntelliJ IDEA在业界被公认为最好的 Java开发工具IDEA 是 JetBrains 公司的产品总部位于捷克的首都布拉格除了支持 Java 开发还支持 HTML CSS PHP MySQL Python 等 8.2 IDE (集成开发环境) -Eclipse 8.2. 1Eclipse 介绍Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。最初是由 IBM 公司耗资3000 万美金开发的下一代 IDE 开发环境2001 年 11 月贡献给开源社区Eclipse 是目前最优秀的 Java 开发 IDE 之一 8.3 IDE (集成开发环境) -IDEA 的使用 8.3. 1IDEA 的安装官网: https://www.jetbrains.com/IDEA 下载后就可以开始安装。看老师给同学们演示如何安装IDEA 工作界面介绍
老韩建议
使用老师讲课用的版本学习起来比较顺畅老师从官网下载的 IDEA 2020.2 会提供给各位 8.3.2IDEA 的基本介绍和使用 使用 IDEA 创建 Java 项目(project) 看看 IDEA 是如何使用的IDEA 是以项目的概念来管理我们的java 源码的 1) 创建一个java 项目 - hello
5min 练习一下.
public class Hello { public static void main(String[] args) { System.out.println(“hello, idea, 你好北京~~”); } }
8.3.3IDEA 使用技巧和经验 设置字体 [如图] 和 颜色主题
菜单 file - settings
字符编码设置
8.3.4课堂练习 使用 IDEA 开发一个java 项目 testpro01创建一个类 MyTools, 编写一个方法可以完成对 int 数组冒泡排序的功能 学员练习 使用快捷键的开发项目
8.3.5IDEA 常用快捷键
删除当前行, 默认是 ctrl Y 自己配置 ctrl d复制当前行, 自己配置 ctrl alt 向下光标补全代码 alt /添加注释和取消注释 ctrl / 【第一次是添加注释第二次是取消注释】导入该行需要的类 先配置 auto import , 然后使用 altenter 即可快速格式化代码 ctrl alt L快速运行程序 自己定义 alt R生成构造器等 alt insert [提高开发效率]查看一个类的层级关系 ctrl H [学习继承后非常有用]将光标放在一个方法上输入 ctrl B , 可以定位到方法 [学继承后非常有用]自动的分配变量名 , 通过 在后面假 .var [老师最喜欢的]还有很多其它的快捷键… 8.3.6模板/自定义模板
8.4 包 8.4. 1看一个应用场景
8.4.2包的三大作用
8.4.3包基本语法
8.4.4包的本质分析(原理)
8.4.5快速入门
8.4.6包的命名
8.4.7常用的包 一个包下,包含很多的类,java 中常用的包有:
java.lang.* //lang 包是基本包默认引入不需要再引入.java.util.* //util 包系统提供的工具包, 工具类使用 Scannerjava.net.* //网络包网络开发java.awt.* //是做java 的界面开发GUI 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 Arrays.sort(arr); //输出排序结果 for (int i 0; i arr.length ; i) { System.out.print(arr[i] “\t”); }
} } 8.4.9注意事项和使用细节
//package 的作用是声明当前类所在的包需要放在类(或者文件)的最上面 // 一个类中最多只有一句 package package com.hspedu.pkg;
//import 指令 位置放在 package 的下面在类定义前面,可以有多句且没有顺序要求 import java.util.Scanner; import java.util.Arrays; //…
//类定义 public class PkgDetail {
public static void main(String[] args) { Scanner scanner new Scanner(System.in); int[] arr {0, - 1, 1}; Arrays.sort(args);
} } 8.5 访问修饰符 8.5. 1基本介绍 java 提供四种访问控制修饰符号用于控制方法和属性(成员变量)的访问权限 (范围) :
公开级别:用 public 修饰,对外公开受保护级别:用 protected 修饰,对子类和同一个包中的类公开默认级别:没有修饰符号, 向同一个包的类公开.私有级别:用 private 修饰, 只有类本身可以访问,不对外公开. 8.5.24 种访问修饰符的访问范围 背下来 8.5.3使用的注意事项
代码:
package com.hspedu.modifier;
public class A {
//四个属性,分别使用不同的访问修饰符来修饰 public int n1 100; protected int n2 200; int n3 300; private int n4 400; public void m1() { //在同一类中可以访问 public protected 默认 private 修饰属性和方法 System.out.println(“n1” n1 n2 n2 n3 n3 n4 n4); } protected void m2() { } void m3() { } private void m4() { } public void hi() { //在同一类中可以访问 public protected 默认 private 修饰属性和方法 m1(); m2(); m3(); m4(); } } package com.hspedu.modifier;
public class B {
public void say() { A a new A(); //在同一个包下可以访问 public , protected 和 System.out.println(“n1” a.n1 n2 a.n2
默认修饰属性或方法,不能访问 private 属性或方法 n3 a.n3 );
a.m1(); a.m2(); a.m3(); //a.m4(); 错误的 }
} package com.hspedu.modifier;
public class Test { public static void main(String[] args) { A a new A (); a.m1(); B b new B(); b.say(); } }
//只有 默认和 public 可以修饰类 class Tiger{ }
8.6 面向对象编程三大特征 8.6. 1基本介绍 面向对象编程有三大特征封装、继承和多态。 8.6.2封装介绍
8.6.3封装的理解和好处
8.6.4封装的实现步骤 (三步)
8.7 快速入门案例 看一个案例
package com.hspedu.encap; public class Encapsulation01 {
public static void main(String[] args) { //如果要使用快捷键 altr, 需要先配置主类 //第一次我们使用鼠标点击形式运算程序后面就可以用 Person person new Person(); person.setName(“韩顺平”); person.setAge(30); person.setSalary(30000); System.out.println(person.info()); System.out.println(person.getSalary());
//如果我们自己使用构造器指定属性 Person smith new Person(“smith”, 80, 50000); System.out.println(“smith 的信息”); System.out.println(smith.info());
} } /* 那么在java 中如何实现这种类似的控制呢? 请大家看一个小程序(com.hspedu.encap: Encapsulation01.java), 不能随便查看人的年龄,工资等隐私并对设置的年龄进行合理的验证。年龄合理就设置否则给默认 年龄, 必须在 1- 120, 年龄 工资不能直接查看 name 的长度在 2-6 字符 之间
*/ class Person { public String name; //名字公开 private int age; //age 私有化 private double salary; //…
public void say(int n,String name) {
} //构造器 altinsert public Person() { } //有三个属性的构造器 public Person(String name, int age, double salary) { // // // this.name name; this.age age; this.salary salary;
//我们可以将 set 方法写在构造器中这样仍然可以验证 setName(name); setAge(age); setSalary(salary); }
//自己写 setXxx 和 getXxx 太慢我们使用快捷键 //然后根据要求来完善我们的代码. public String getName() { return name; } public void setName(String name) { //加入对数据的校验,相当于增加了业务逻辑 if(name.length() 2 name.length() 6 ) { this.name name; }else { System.out.println(“名字的长度不对需要(2-6)个字符默认名字”); this.name “无名人”; } }
public int getAge() { return age; }
public void setAge(int age) {
//判断 if(age 1 age 120) {//如果是合理范围 this.age age; } else { System.out.println(你设置年龄不对需要在 ( 1- 120), 给默认年龄 18 ); this.age 18;//给一个默认年龄 } }
public double getSalary() { //可以这里增加对当前对象的权限判断 return salary; }
public void setSalary(double salary) { this.salary salary; } //写一个方法返回属性信息 public String info() { return “信息为 name” name age age 薪水 salary; } }
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.7.2课堂练习
package com.hspedu.encap;
/**
创建程序,在其中定义两个类Account 和 AccountTest 类体会 Java 的封装性。Account 类要求具有属性姓名 (长度为 2 位 3 位或 4 位) 、余额(必须20)、密码 (必须是六位) , 如果不满足则给出提示信息并给默认值(程序员自己定)通过 setXxx 的方法给 Account 的属性赋值。在 AccountTest 中测试
*/ public class Account { //为了封装将 3 个属性设置为 private private String name; private double balance; private String pwd;
//提供两个构造器 public Account() { }
public Account(String name, double balance, String pwd) { this.setName(name); this.setBalance(balance); this.setPwd(pwd); }
public String getName() { return name; }
//姓名 (长度为 2 位 3 位或 4 位) public void setName(String name) { if (name.length() 2 name.length() 4) { this.name name; } else {
System.out.println(“姓名要求 (长度为 2 位 3 位或 4 位) 默认值 无名”); this.name “无名”; } }
public double getBalance() { return balance; }
//余额(必须20) public void setBalance(double balance) { if (balance 20) { this.balance balance; } else { System.out.println(“余额(必须20) 默认为 0”); } }
public String getPwd() { return pwd; }
//密码 (必须是六位) public void setPwd(String pwd) { if (pwd.length() 6) { this.pwd pwd;
} else { System.out.println(“密码 (必须是六位) 默认密码为 000000”); this.pwd “000000”; } } //显示账号信息 public void showInfo() { //可以增加权限的校验 System.out.println(“账号信息 name” name 余额 balance 密码 pwd); // // // // // } } if() { System.out.println(“账号信息 name” name 余额 balance 密码); }else{ System.out.println(“你无权查看…”); } package com.hspedu.encap;
public class TestAccount { public static void main(String[] args) { //创建 Account Account account new Account(); account.setName(“jack”); account.setBalance(60); account.setPwd(“123456”);
account.showInfo(); } }
8.8 面向对象编程-继承 8.8. 1为什么需要继承
8.8.2继承基本介绍和示意图 继承可以解决代码复用,让我们的编程更加靠近人类思维. 当多个类存在相同的属性(变量)和方法时,可以从这些类中 抽象出父类,在父类中定义这些相同的属性和方法所有的子类不需要重新定义这些属性和方法只需要通过 extends 来 声明继承父类即可。画出继承的示意图
8.8.3继承的基本语法
8.8.4快速入门案例 我们对Extends01.java 改进使用继承的方法,请大家注意体会使用继承的好处
package com.hspedu.extend_.improve_;
import com.hspedu.extend_.Graduate; import com.hspedu.extend_.Pupil;
public class Extends01 { public static void main(String[] args) { com.hspedu.extend_.Pupil pupil new Pupil(); pupil.name “银角大王~”; pupil.age 11; pupil.testing(); pupil.setScore(50); pupil.showInfo();
System.out.println(“”); com.hspedu.extend_.Graduate graduate new Graduate(); graduate.name “金角大王~”;
graduate.age 23; graduate.testing(); graduate.setScore(80); graduate.showInfo(); } } package com.hspedu.extend_.improve_;
//父类,是 Pupil 和 Graduate 的父类 public class Student { //共有属性 public String name; public int age; private double score;//成绩 //共有的方法 public void setScore(double score) { this.score score; }
public void showInfo() { System.out.println(学生名 name 年龄 age 成绩 score); } } package com.hspedu.extend_.improve_; //让 Pupil 继承 Student 类
public class Pupil extends Student { public void testing() { System.out.println(“小学生 name 正在考小学数学…”); } } package com.hspedu.extend_.improve_; public class Graduate extends Student {
public void testing() {//和 Pupil 不一样 System.out.println(“大学生 name 正在考大学数学…”); } }
8.8.5继承给编程带来的便利 代码的复用性提高了 代码的扩展性和维护性提高了 8.8.6继承的深入讨论/细节问题 子类继承了所有的属性和方法非私有的属性和方法可以在子类直接访问, 但是私有属性和方法不能在子类直接访 问要通过父类提供公共的方法去访问 子类必须调用父类的构造器 完成父类的初始化 当创建子类对象时不管使用子类的哪个构造器默认情况下总会去调用父类的无参构造器如果父类没有提供无 参构造器则必须在子类的构造器中用 super 去指定使用父类的哪个构造器完成对父类的初始化工作否则编译
不会通过(怎么理解。) [举例说明] 4) 如果希望指定去调用父类的某个构造器则显式的调用一下 : super(参数列表) 5) super 在使用时必须放在构造器第一行(super 只能在构造器中使用) 6) super() 和 this() 都只能放在构造器第一行因此这两个方法不能共存在一个构造器 7) java 所有类都是 Object 类的子类, Object 是所有类的基类. 8) 父类构造器的调用不限于直接父类将一直往上追溯直到 Object 类(顶级父类) 9) 子类最多只能继承一个父类(指直接继承) 即java 中是单继承机制。 思考如何让 A 类继承 B 类和C 类 【A 继承 B B 继承 C】 10) 不能滥用继承子类和父类之间必须满足 is-a 的逻辑关系 代码
package com.hspedu.extend_;
public class ExtendsDetail { public static void main(String[] args) {
// System.out.println(“第 1 个对象”); // Sub sub new Sub(); //创建了子类对象 sub // System.out.println(“第 2 个对象”); // Sub sub2 new Sub(“jack”); //创建了子类对象 sub2 System.out.println(“第 3 对象”); Sub sub3 new Sub(“king”, 10); //创建了子类对象 sub2 //sub.sayOk(); } }
package com.hspedu.extend_;
public class Base extends TopBase { //父类 //4 个属性 public int n1 100; protected int n2 200; int n3 300; private int n4 400;
public Base() { //无参构造器 System.out.println(“父类 Base()构造器被调用…”); } public Base(String name, int age) {//有参构造器 //默认 super() System.out.println(“父类 Base(String name, int age)构造器被调用…”); } public Base(String name) {//有参构造器 System.out.println(“父类 Base(String name)构造器被调用…”); } //父类提供一个 public 的方法,返回了 n4 public int getN4() { return n4; } public void test 100() { System.out.println(“test 100”); } protected void test200() { System.out.println(“test200”);
} void test300() { System.out.println(“test300”); } private void test400() { System.out.println(“test400”); } //call public void callTest400() { test400(); } }
package com.hspedu.extend_; import java.util.Arrays;
//输入 ctrl H 可以看到类的继承关系 public class Sub extends Base { //子类
public Sub(String name, int age) { //1. 老师要调用父类的无参构造器, 如下或者 什么都不写,默认就是调用 super() //super();//父类的无参构造器 //2. 老师要调用父类的 Base(String name) 构造器 //super(“hsp”); //3. 老师要调用父类的 Base(String name, int age) 构造器
super(“king”, 20);
//细节 super 在使用时必须放在构造器第一行 //细节: super() 和 this() 都只能放在构造器第一行因此这两个方法不能共存在一个构造器 //this() 不能再使用了 System.out.println(“子类 Sub(String name, int age)构造器被调用…”);
}
public Sub() {//无参构造器 //super(); //默认调用父类的无参构造器 super(“smith”, 10); System.out.println(“子类 Sub()构造器被调用…”); } //当创建子类对象时不管使用子类的哪个构造器默认情况下总会去调用父类的无参构造器 public Sub(String name) { super(“tom”, 30); //do nothing… System.out.println(“子类 Sub(String name)构造器被调用…”); }
public void sayOk() {//子类方法 //非私有的属性和方法可以在子类直接访问 //但是私有属性和方法不能在子类直接访问 System.out.println(n1 n2 n3);
test 100(); test200(); test300(); //test400();错误 //要通过父类提供公共的方法去访问 System.out.println(“n4” getN4()); callTest400();// } }
package com.hspedu.extend_;
public class TopBase { //父类是 Object
public TopBase() { //super(); Object 的无参构造器 System.out.println(“构造器 TopBase() 被调用…”);//1 } }
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 “大头儿子”; }
子类创建的内存布局
8.8.8课堂练习 案例 1 ExtendsExercise01.java 案例 2 ExtendsExercise02.java
package com.hspedu.extend_.exercise;
public class ExtendsExercise02 { public static void main(String[] args) { C c new C(); } }
class A {//A 类
public A() { System.out.println(“我是 A 类”); } }
class B extends A { //B 类,继承 A 类 //main 方法中 C c new C(); 输出么内容? 3min public B() { System.out.println(“我是 B 类的无参构造”); }
public B(String name) { System.out.println(name “我是 B 类的有参构造”); } }
class C extends B { //C 类继承 B 类 public C() { this(“hello”); System.out.println(“我是 c 类的无参构造”); }
public C(String name) { super(“hahah”);
System.out.println(“我是 c 类的有参构造”); } }
案例 3 ExtendsExercise03.java 编写 Computer 类包含 CPU 、内存、硬盘等属性getDetails 方法用于返回 Computer 的详细信息 编写 PC 子类继承 Computer 类添加特有属性【品牌 brand】 编写 NotePad 子类继承 Computer 类添加特有属性【color】 编写 Test 类在 main 方法中创建 PC 和 NotePad 对象分别给对象中特有的属性赋值 以及从 Computer 类继承的 属性赋值并使用方法并打印输出信息
package com.hspedu.extend_.exercise;
//编写 Computer 类包含 CPU 、内存、硬盘等属性getDetails 方法用于返回 Computer 的详细信息 public class Computer { private String cpu; private int memory; private int disk; public Computer(String cpu, int memory, int disk) { this.cpu cpu; this.memory memory; this.disk disk; } //返回 Computer 信息 public String getDetails() { return “cpu” cpu memory memory disk disk; }
public String getCpu() { return cpu; }
public void setCpu(String cpu) { this.cpu cpu; }
public int getMemory() { return memory; }
public void setMemory(int memory) { this.memory memory; }
public int getDisk() { return disk; }
public void setDisk(int disk) { this.disk disk; } }
package com.hspedu.extend_.exercise;
//编写 PC 子类继承 Computer 类添加特有属性【品牌 brand】 public class PC extends Computer{
private String brand; //这里 IDEA 根据继承的规则 自动把构造器的调用写好 //这里也体现 继承设计的基本思想父类的构造器完成父类属性初始化 //子类的构造器完成子类属性初始化 public PC(String cpu, int memory, int disk, String brand) { super(cpu, memory, disk); this.brand brand; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand brand; } public void printInfo() { System.out.println(“PC 信息”); //
} System.out.println(getCpu() getMemory() getDisk()); //调用父类的 getDetails 方法得到相关属性信息… System.out.println(getDetails() brand brand);
} package com.hspedu.extend_.exercise;
public class ExtendsExercise03 { public static void main(String[] args) { PC pc new PC(“intel”, 16, 500, “IBM”); pc.printInfo(); } } /* 编写 Computer 类包含 CPU 、内存、硬盘等属性getDetails 方法用于返回 Computer 的详细信息 编写 PC 子类继承 Computer 类添加特有属性【品牌 brand】 编写 NotePad 子类继承 Computer 类添加特有属性【color】//同学们自己写。 编写 Test 类在 main 方法中创建 PC 和 NotePad 对象分别给对象中特有的属性赋值 以及从 Computer 类继承的属性赋值并使用方法并打印输出信息 */
8.9 super 关键字 8.9. 1基本介绍 super 代表父类的引用用于访问父类的属性、方法、构造器 8.9.2基本语法
代码
package com.hspedu.super_;
public class A extends Base{ //4 个属性 //public int n1 100; protected int n2 200; int n3 300; private int n4 400;
public A() {} public A(String name) {} public A(String name, int age) {}
// public void cal() { // System.out.println(“A 类的 cal() 方法…”); // }
public void test 100() { }
protected void test200() { }
void test300() { }
private void test400() { } } package com.hspedu.super_; public class B extends A {
public int n1 888;
//编写测试方法 public void test() { //super 的访问不限于直接父类如果爷爷类和本类中有同名的成员也可以使用 super 去访问爷爷类的成员 // 如果多个基类(上级类)中都有同名的成员使用 super 访问遵循就近原则。A-B-C
System.out.println(“super.n1” super.n1); super.cal(); }
//访问父类的属性 , 但不能访问父类的 private 属性 [案例]super.属性名 public void hi() { System.out.println(super.n1 super.n2 super.n3 ); } public void cal() { System.out.println(“B 类的 cal() 方法…”); } public void sum() { System.out.println(“B 类的 sum()”); //希望调用父类-A 的 cal 方法 //这时因为子类 B 没有 cal 方法因此我可以使用下面三种方式
//找 cal 方法时(cal() 和 this.cal()) 顺序是: // (1)先找本类如果有则调用 // (2)如果没有则找父类(如果有并可以调用则调用) // (3)如果父类没有则继续找父类的父类,整个规则就是一样的,直到 Object 类 // 提示如果查找方法的过程中找到了但是不能访问 则报错, cannot access // 如果查找方法的过程中没有找到则提示方法不存在 //cal(); this.cal(); //等价 cal
//找 cal 方法(super.call()) 的顺序是直接查找父类其他的规则一样 //super.cal();
//演示访问属性的规则
//n1 和 this.n1 查找的规则是 //(1) 先找本类如果有则调用 //(2) 如果没有则找父类(如果有并可以调用则调用) //(3) 如果父类没有则继续找父类的父类,整个规则就是一样的,直到 Object 类 // 提示如果查找属性的过程中找到了但是不能访问 则报错, cannot access // 如果查找属性的过程中没有找到则提示属性不存在 System.out.println(n1); System.out.println(this.n1);
//找 n1 (super.n1) 的顺序是直接查找父类属性其他的规则一样 System.out.println(super.n1);
} //访问父类的方法不能访问父类的 private 方法 super.方法名(参数列表); public void ok() { super.test 100(); super.test200(); super.test300(); //super.test400();//不能访问父类 private 方法 } //访问父类的构造器(这点前面用过)super(参数列表);只能放在构造器的第一句只能出现一句 public B() { //super(); //super(“jack”, 10); super(“jack”); }
} package com.hspedu.super_;
public class Super01 { public static void main(String[] args) { B b new B();//子类对象 //b.sum(); b.test(); } } package com.hspedu.super_; public class Base { //父类是 Object
public int n1 999; public int age 111; public void cal() { System.out.println(“Base 类的 cal() 方法…”); } public void eat() { } }
8.9.3super 给编程带来的便利/细节
代码, 看前面的案例即可 8.9.4super 和 this 的比较 10 方法重写/覆盖(override) 1 基本介绍 10.2 快速入门 代码
package com.hspedu.override_;
public class Animal { public void cry() { System.out.println(“动物叫唤…”); }
public Object m1() { return null; }
public String m2() { return null; }
public AAA m3() { return null; } protected void eat() { }
} package com.hspedu.override_;
public class Dog extends Animal{ //老韩解读 //1. 因为 Dog 是 Animal 子类 //2. Dog 的 cry 方法和 Animal 的 cry 定义形式一样(名称、返回类型、参数) //3. 这时我们就说 Dog 的 cry 方法重写了 Animal 的 cry 方法 public void cry() { System.out.println(“小狗汪汪叫…”); }
//细节: 子类方法的返回类型和父类方法返回类型一样 // 或者是父类返回类型的子类 比如 父类 返回类型是 Object , // 子类方法返回类型是 String public String m1() { return null; } //这里 Object 不是 String 的子类因此编译错误 // public Object m2() { // return null; // }
// public BBB m3() {
// return null; // } //细节: 子类方法不能缩小父类方法的访问权限 【演示】 //public protected 默认private public void eat() {
} }
class AAA { }
class BBB extends AAA { } package com.hspedu.override_;
public class Override01 { public static void main(String[] args) { //演示方法重写的情况 Dog dog new Dog(); dog.cry();//ctrlb } } 10.3 注意事项和使用细节 方法重写也叫方法覆盖需要满足下面的条件 10.4 课堂练习 题 1 请对方法的重写和重载做一个比较
题 2
编写一个 Person 类包括属性/private (name 、age) 构造器、方法 say(返回自我介绍的字符串) 。编写一个 Student 类继承 Person 类增加 id、score 属性/private 以及构造器定义 say 方法(返回自我介绍的信息)。 3) 在 main 中,分别创建 Person 和 Student 对象调用 say 方法输出自我介绍 代码
package com.hspedu.override_;
//编写一个 Person 类包括属性/private (name 、age) 构造器、方法 say(返回自我介绍的字符串) public class Person { private String name; private int age; public Person(String name, int age) { this.name name; this.age age; } public String say() { return “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; } } package com.hspedu.override_;
//编写一个 Student 类继承 Person 类增加 id 、score 属性/private 以及构造器定义 say 方法(返回自我介绍的信息)。 public class Student extends Person{ private int id; private double score;
public Student(String name, int age, int id, double score) { super(name, age);//这里会调用父类构造器 this.id id; this.score score; } //say public String say() { //这里体现 super 的一个好处代码复用. return super.say() id id score score; } public int getId() { return id; }
public void setId(int id) {
this.id id; }
public double getScore() { return score; }
public void setScore(double score) { this.score score; } } package com.hspedu.override_;
public class OverrideExercise { public static void main(String[] args) { //在 main 中,分别创建 Person 和 Student 对象调用 say 方法输出自我介绍 Person jack new Person(“jack”, 10); System.out.println(jack.say());
Student smith new Student(“smith”, 20, 123456, 99.8); System.out.println(smith.say()); } }
11 面向对象编程-多态 1 先看一个问题
使用传统的方法来解决 (private 属性) 传统的方法带来的问题是什么? 如何解决? 问题是 代码的复用性不高而且不利于代码维护 解决方案 引出我们要讲解的多态 代码:
package com.hspedu.poly_;
public class Animal { private String name;
public Animal(String name) { this.name name; }
public String getName() { return name; }
public void setName(String name) { this.name name; } } package com.hspedu.poly_;
public class Bone extends Food { public Bone(String name) { super(name); } } package com.hspedu.poly_;
public class Cat extends Animal { public Cat(String name) { super(name); } } package com.hspedu.poly_;
public class Dog extends Animal { public Dog(String name) {
super(name); } } package com.hspedu.poly_;
public class Fish extends Food { public Fish(String name) { super(name); } } package com.hspedu.poly_;
public class Food { private String name;
public Food(String name) { this.name name; }
public String getName() { return name; }
public void setName(String name) { this.name name; }
} package com.hspedu.poly_;
public class Master { private String name;
public Master(String name) { this.name name; }
public String getName() { return name; }
public void setName(String name) { this.name name; }
//使用多态机制可以统一的管理主人喂食的问题 //animal 编译类型是 Animal,可以指向(接收)Animal 子类的对象 //food 编译类型是 Food ,可以指向(接收) Food 子类的对象 public void feed(Animal animal, Food food) { System.out.println(主人 name 给 animal.getName() 吃 food.getName()); }
//主人给小狗 喂食 骨头
// public void feed(Dog dog, Bone bone) { // System.out.println(主人 name 给 dog.getName() 吃 bone.getName()); // } // //主人给 小猫喂 黄花鱼 // public void feed(Cat cat, Fish fish) { // System.out.println(主人 name 给 cat.getName() 吃 fish.getName()); // }
//如果动物很多食物很多 // feed 方法很多不利于管理和维护 //Pig -- Rice //Tiger — meat … //…
} package com.hspedu.poly_;
public class Pig extends Animal { public Pig(String name) { super(name); } } package com.hspedu.poly_;
public class Rice extends Food { public Rice(String name) {
super(name); } }
11.2 多[多种]态[状态]基本介绍 方法或对象具有多种形态。是面向对象的第三大特征多态是建立在封装和继承基础之上的。11.3 多态的具体体现
方法的多态 PloyMethod.java 重写和重载就体现多态 [案例说明]
package com.hspedu.poly_;
public class PloyMethod { public static void main(String[] args) { //方法重载体现多态 A a new A(); //这里我们传入不同的参数就会调用不同 sum 方法就体现多态 System.out.println(a.sum( 10, 20)); System.out.println(a.sum( 10, 20, 30));
//方法重写体现多态 B b new B(); a.say(); b.say();
} } class B { //父类 public void say() { System.out.println(“B say() 方法被调用…”); } } class A extends B {//子类 public int sum(int n1, int n2){//和下面 sum 构成重载 return n1 n2; } public int sum(int n1, int n2, int n3){ return n1 n2 n3; }
public void say() { System.out.println(“A say() 方法被调用…”); } }
对象的多态 (核心困难重点)
代码
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(); //小猫喵喵叫 } } 11.4 多态快速入门案例 使用多态的机制来解决主人喂食物的问题走代码。 Poly01.java 11.5 多态注意事项和细节讨论 com.hspedu.poly_.detail_ 包 : PolyDetail.java 多态的前提是两个对象(类)存在继承关系 多态的向上转型
多态向下转型
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~~”); } }
属性没有重写之说属性的值看编译类型 PolyDetail02.java
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 类型的子类型【举例说明】PolyDetail03.javapackage 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 {}//子类
11.6 课堂练习 请说出下面的每条语言哪些是正确的哪些是错误的为什么? 2min 后老师评讲
PolyExercise02.java 3min
11.7 java 的动态绑定机制(非常非常重要.) 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; // } }
11.8 多态的应用
多态数组 com.hspedu.poly_.polyarr_ 包 PloyArray.java 数组的定义类型为父类类型里面保存的实际元素类型为子类类型
应用实例:现有一个继承结构如下要求创建 1 个 Person 对象、2 个 Student 对象和 2 个 Teacher 对象, 统一放在数组 中并调用每个对象 say 方法.
应用实例升级如何调用子类特有的方法比如 Teacher 有一个 teach , Student 有一个 study 怎么调用 代码:
package com.hspedu.poly_.polyarr_;
public class Person {//父类 private String name; private int age;
public Person(String name, int age) { this.name name; this.age age; }
public String getName() {
return name; }
public void setName(String name) { this.name name; }
public int getAge() { return age; }
public void setAge(int age) { this.age age; }
public String say() {//返回名字和年龄 return name “\t” age; } } package com.hspedu.poly_.polyarr_;
public class Student extends Person { private double score;
public Student(String name, int age, double score) {
super(name, age); this.score score; }
public double getScore() { return score; }
public void setScore(double score) { this.score score; } //重写父类 say
Override public String say() { return “学生 super.say() score” score; } //特有的方法 public void study() { System.out.println(“学生 getName() 正在学java…”); } } package com.hspedu.poly_.polyarr_;
public class Teacher extends Person {
private double salary;
public Teacher(String name, int age, double salary) { super(name, age); this.salary salary; }
public double getSalary() { return salary; }
public void setSalary(double salary) { this.salary salary; } //写重写父类的 say 方法
Override public String say() { return “老师 super.say() salary” salary; } //特有方法 public void teach() { System.out.println(“老师 getName() 正在讲java 课程…”); } }
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){ //System.out.println(“你的类型有误, 请自己检查…”); } else { System.out.println(“你的类型有误, 请自己检查…”); }
}
} }
多态参数
代码:
package com.hspedu.poly_.polyparameter_;
public class Employee {
private String name; private double salary;
public Employee(String name, double salary) { this.name name; this.salary salary; } //得到年工资的方法 public double getAnnual() { return 12 * salary; }
public String getName() { return name; }
public void setName(String name) { this.name name; }
public double getSalary() { return salary; }
public void setSalary(double salary) { this.salary salary;
} } package com.hspedu.poly_.polyparameter_; public class Manager extends Employee{
private double bonus;
public Manager(String name, double salary, double bonus) { super(name, salary); this.bonus bonus; }
public double getBonus() { return bonus; }
public void setBonus(double bonus) { this.bonus bonus; } public void manage() { System.out.println(“经理 getName() is managing”); } //重写获取年薪方法 Override
public double getAnnual() { return super.getAnnual() bonus; } } package com.hspedu.poly_.polyparameter_;
public class Worker extends Employee { public Worker(String name, double salary) { super(name, salary); } public void work() { System.out.println(“普通员工 getName() is working”); }
Override public double getAnnual() { //因为普通员工没有其它收入则直接调用父类方法 return super.getAnnual(); } } package com.hspedu.poly_.polyparameter_;
public class PloyParameter { public static void main(String[] args) { Worker tom new Worker(“tom”, 2500);
Manager milan new Manager(“milan”, 5000, 200000); PloyParameter ployParameter new PloyParameter(); ployParameter.showEmpAnnual(tom); ployParameter.showEmpAnnual(milan);
ployParameter.testWork(tom); ployParameter.testWork(milan);
}
//showEmpAnnual(Employee e) //实现获取任何员工对象的年工资,并在 main 方法中调用该方法 [e.getAnnual()] public void showEmpAnnual(Employee e) { System.out.println(e.getAnnual());//动态绑定机制. } //添加一个方法testWork,如果是普通员工则调用 work 方法如果是经理则调用 manage 方法 public void testWork(Employee e) { if(e instanceof Worker) { ((Worker) e).work();//有向下转型操作 } else if(e instanceof Manager) { ((Manager) e).manage();//有向下转型操作 } else { System.out.println(“不做处理…”); } } }
12 Object 类详解 1 equals 方法 和 equals 的对比 [面试题]
package com.hspedu.object_; public class Equals01 {
public static void main(String[] args) { A a new A(); A b a; A c b; System.out.println(a c);//true System.out.println(b c);//true B bObj a; System.out.println(bObj c);//true int num1 10;
double num2 10.0; System.out.println(num1 num2);//基本数据类型判断值是否相等
//equals 方法源码怎么查看. //把光标放在 equals 方法直接输入 ctrlb //如果你使用不了. 自己配置. 即可使用.
/* //带大家看看 Jdk 的源码 String 类的 equals 方法 //把 Object 的 equals 方法重写了,变成了比较两个字符串值是否相同 public boolean equals(Object anObject) { if (this anObject) {//如果是同一个对象 return true;//返回 true } if (anObject instanceof String) {//判断类型 String anotherString (String)anObject;//向下转型 int n value.length; if (n anotherString.value.length) {//如果长度相同 char v1[] value; char v2[] anotherString.value; int i 0; while (n-- ! 0) {//然后一个一个的比较字符 if (v1[i] ! v2[i]) return false; i; }
return true;//如果两个字符串的所有字符都相等则返回 true } } return false;//如果比较的不是字符串则直接返回 false } */
“hello”.equals(“abc”);
//看看 Object 类的 equals 是 /* //即 Object 的 equals 方法默认就是比较对象地址是否相同 //也就是判断两个对象是不是同一个对象. public boolean equals(Object obj) { return (this obj); } */
/* //从源码可以看到 Integer 也重写了 Object 的 equals 方法, //变成了判断两个值是否相同 public boolean equals(Object obj) { if (obj instanceof Integer) { return value ((Integer)obj).intValue();
} return false; } */ Integer integer1 new Integer( 1000); Integer integer2 new Integer( 1000); System.out.println(integer1 integer2);//false System.out.println(integer1.equals(integer2));//true
String str1 new String(“hspedu”); String str2 new String(“hspedu”); System.out.println(str1 str2);//false System.out.println(str1.equals(str2));//true
} }
class B {} class A extends B {}
12.2 如何重写 equals 方法 应用实例: 判断两个 Person对象的内容是否相等如果两个 Person对象的各个属性值都一样则返回 true反之false。
EqualsExercise01.java
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;
}
public Person(String name, int age, char gender) { this.name name; this.age age; this.gender gender; }
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 char getGender() { return gender; }
public void setGender(char gender) { this.gender gender; } } 8. 12.3 课堂练习题
package com.hspedu.object_;
public class EqualsExercise02 { public static void main(String[] args) {
Person_ p1 new Person_(); p1.name “hspedu”;
Person_ p2 new Person_(); p2.name “hspedu”;
System.out.println(p1p2); //False System.out.println(p1.name .equals( p2.name));//T System.out.println(p1.equals(p2));//False String s1 new String(“asdf”);
String s2 new String(“asdf”); System.out.println(s1.equals(s2));//T System.out.println(s1s2); //F
} }
class Person_ {//类 public String name; }
代码如下 EqualsExercise03.java 2min
//代码如下 EqualsExercise03.java 2min int it 65; float fl 65.0f; System.out.println(“65 和 65.0f 是否相等” (it fl));//T
char ch 1 ‘A’; char ch2 12; System.out.println(“65 和‘A’是否相等” (it ch 1));//T System.out.println(“12 和 ch2 是否相等” (12 ch2));//T
String str1 new String(“hello”); String str2 new String(“hello”); System.out.println(“str1 和 str2 是否相等” (str1 str2)); //F
System.out.println(“str1 是否 equals str2”(str1.equals(str2)));//T System.out.println(“hello” new java.sql.Date()); //编译错误
12.4 hashCode 方法
老韩的6 个小结: 提高具有哈希结构的容器的效率 两个引用如果指向的是同一个对象则哈希值肯定是一样的 两个引用如果指向的是不同对象则哈希值是不一样的 哈希值主要根据地址号来的 不能完全将哈希值等价于地址。 案例演示[HashCode_.java]: obj.hashCode() [测试A obj1 new A(); A obj2 new A(); A obj3 obj1] 后面在集合中 hashCode 如果需要的话也会重写, 在讲解集合时老韩在说如何重写 hashCode() 代码
package com.hspedu.object_;
public class HashCode_ { public static void main(String[] args) {
AA aa new AA(); AA aa2 new AA(); AA aa3 aa; System.out.println(“aa.hashCode()” aa.hashCode()); System.out.println(“aa2.hashCode()” aa2.hashCode()); System.out.println(“aa3.hashCode()” aa3.hashCode());
} } class AA {}
12.5 toString 方法
基本介绍 默认返回全类名哈希值的十六进制【查看 Object 的 toString 方法】 子类往往重写 toString 方法用于返回对象的属性信息重写 toString 方法打印对象或拼接对象时都会自动调用该对象的 toString 形式.
案例演示Monster [name, job, sal] 案例: ToString_.java 3) 当直接输 出 一个对 象 时 toString 方法会被默认 的调用 , 比 如 System.out.println(monster) 就会默认调用 monster.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 方法, 输出对象的属性 //使用快捷键即可 altinsert - 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 方法 当对象被回收时系统自动调用该对象的finalize 方法。子类可以重写该方法做一些释放资源的操作【演示】 什么时候被回收当某个对象没有任何引用时则jvm 就认为这个对象是一个垃圾对象就会使用垃圾回收机制来 销毁该对象在销毁该对象前会先调用 finalize 方法。 垃圾回收机制的调用是由系统来决定(即有自己的 GC 算法), 也可以通过 System.gc() 主动触发垃圾回收机制测 试Car [name] 老韩提示 我们在实际开发中几乎不会运用 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(“释放了某些资源…”);
} } 13 断点调试(debug) 1 一个实际需求 13.2 断点调试介绍 13.3 断点调试的快捷键 F7(跳入) F8(跳过) shiftF8(跳出) F9(resume,执行到下一个断点) F7跳入方法内 F8: 逐行执行代码. shiftF8: 跳出方法 13.4 断点调试应用案例 看几段代码演示调试过程 13.5 断点调试应用案例
案例 1 com.hspedu.debug_ 包 Debug01.java 看一下变量的变化情况等
package com.hspedu.debug_;
public class Debug01 { public static void main(String[] args) { //演示逐行执行代码 int sum 0; for (int i 0; i 5; i) { sum i; System.out.println(“i” i); System.out.println(“sum” i); } System.out.println(“退出 for…”); } }
案例 2 看一下数组越界的异常 Debug02.java
package com.hspedu.debug_;
public class Debug02 { public static void main(String[] args) { int[] arr { 1, 10, - 1}; for (int i 0; i arr.length; i) { System.out.println(arr[i]); } System.out.println(“退出 for”); } }
案例 3 演示如何追源码看看java 设计者是怎么实现的。(提高编程思想)。 小技巧将光标放在某个变量上可以看到最新的数据。 Debug03.java
package com.hspedu.debug_; import java.util.Arrays;
public class Debug03 { public static void main(String[] args) { int[] arr { 1, - 1, 10, -20 , 100}; //我们看看 Arrays.sort 方法底层实现.-Debug Arrays.sort(arr); for (int i 0; i arr.length; i) { System.out.print(arr[i] “\t”); }
} }
案例 4 演示如何直接执行到下一个断点 F9 resume。 老韩小技巧: 断点可以在 debug 过程中动态的下断点
package com.hspedu.debug_; import java.util.Arrays;
//演示执行到下一个断点同时支持动态的下断点. public class Debug04 { public static void main(String[] args) {
int[] arr { 1, - 1, 10, -20 , 100}; //我们看看 Arrays.sort 方法底层实现.-Debug Arrays.sort(arr); for (int i 0; i arr.length; i) { System.out.print(arr[i] “\t”); }
System.out.println(“hello100”); System.out.println(“hello200”); System.out.println(“hello300”); System.out.println(“hello400”);
System.out.println(“hello500”); System.out.println(“hello600”); System.out.println(“hello700”); } } 8. 13.6 断点调试课后练习
14 项目-零钱通 1 项目开发流程说明 14.2 项目需求说明 使用 Java 开发 零钱通项目 , 可以完成收益入账消费查看明细退出系统等功能.14.3 项目的界面
化繁为简.
先完成显示菜单并可以选择完成零钱通明细.完成收益入账消费退出
14.4 项目代码实现
编写文件 SmallChangeSys.java 完成基本功能 (过程编程) 老师提示先使用过程编程后面改成 OOP 版本请小伙伴体会 OOP 编程带来的好处 8. 14.5 项目代码实现改进
项目代码打包
smallchange.zip
15 本章作业
第 9 章 项目-房屋出租系统 9. 1 房屋出租系统-需求 9. 1. 1项目需求说明 实现基于文本界面的《房屋出租软件》。 能够实现对房屋信息的添加、修改和删除 (用数组实现) 并能够打印房屋明细表 9.2 房屋出租系统-界面 9.2. 1项目界面 - 主菜单
9.2.2项目界面- 新增房源
9.2.3项目界面- 查找房源
9.2.4项目界面- 删除房源
9.2.5项目界面- 修改房源
9.2.6项目界面- 房屋列表
9.2.7项目界面- 退出系统
9.3 房屋出租系统-设计(!!) 项目设计-程序框架图 (分层模式当软件比较复杂需要模式管理)
9.4 房屋出租系统-实现 9.4. 1准备工具类 Utility 提高开发效率 在实际开发中公司都会提供相应的工具类和开发库可以提高开发效率程序员也需要能够看懂别人写的代码 并能够正确的调用。
了解 Utility 类的使用测试 Utility 类 9.4.2项目功能实现-完成 House 类
编号 房主 电话 地址 月租 状态(未出租/已出租 9.4.3项目功能实现-显示主菜单和完成退出软件功能 老师说明实现功能的三部曲 [明确完成功能-思路分析-代码实现] 功能说明: 用户打开软件 可以看到主菜单可以退出软件.
思路分析: 在 HouseView.java 中编写一个方法 mainMenu,显示菜单.
代码实现 9.4.4项目功能实现-完成显示房屋列表的功能
9.4.5项目功能实现-添加房屋信息的功能
9.4.6项目功能实现-完成删除房屋信息的功能
9.4.7项目功能实现-完善退出确认功能 (课堂作业)
9.4.8项目功能实现-完成根据 id 查找房屋信息的功能 (课后作业) 9.4.9项目功能实现-完成修改房屋信息的功能 (课后作业)
第 10 章面向对象编程(高级部分) 10. 1 类变量和类方法 10. 1. 1 类变量-提出问题 提出问题的主要目的就是让大家思考解决之道从而引出我要讲的知识点. 说有一群小孩在玩堆雪人,不时有新的小孩加入,请问如何知道现在共有多少人在玩? 编写程序解决。 1.2 传统的方法来解决 1.3 类变量快速入门 思考: 如果,设计一个 int count 表示总人数,我们在创建一个小孩时就把 count 加 1,并且 count 是所有对象共享的 就 ok 了! 我们使用类变量来解决 ChildGame.java 改进 代码.
package com.hspedu.static_;
public class ChildGame {
public static void main(String[] args) {
//定义一个变量 count, 统计有多少小孩加入了游戏 int count 0;
Child child1 new Child(“白骨精”); child1.join(); //count; child1.count;
Child child2 new Child(“狐狸精”); child2.join(); //count; child2.count;
Child child3 new Child(“老鼠精”); child3.join(); //count; child3.count;
// //类变量可以通过类名来访问 System.out.println(“共有” Child.count 小孩加入了游戏…); //下面的代码输出什么?
System.out.println(“child1.count” child1.count);//3 System.out.println(“child2.count” child2.count);//3 System.out.println(“child3.count” child3.count);//3 } }
class Child { //类 private String name; //定义一个变量 count ,是一个类变量(静态变量) static 静态 //该变量最大的特点就是会被 Child 类的所有的对象实例共享 public static int count 0; public Child(String name) { this.name name; } public void join() { System.out.println(name 加入了游戏…); } } 10. 1.4 类变量内存布局 1.5 什么是类变量 1.6 如何定义类变量 1.7 如何访问类变量 VisitStatic.java
代码
package com.hspedu.static_;
public class VisitStatic { public static void main(String[] args) {
//类名.类变量名 //说明类变量是随着类的加载而创建所以即使没有创建对象实例也可以访问 System.out.println(A.name); A a new A(); //通过对象名.类变量名 System.out.println(“a.name” a.name);
} }
class A { //类变量 //类变量的访问必须遵守 相关的访问权限. public static String name “韩顺平教育”; //普通属性/普通成员变量/非静态属性/非静态成员变量/实例变量 private int num 10;
} 10. 1.8 类变量使用注意事项和细节讨论 StaticDetail.java
代码:
package com.hspedu.static_;
public class StaticDetail { public static void main(String[] args) { B b new B(); //System.out.println(B.n1); System.out.println(B.n2);
//静态变量是类加载的时候就创建了,所以我们没有创建对象实例 //也可以通过类名.类变量名来访问
System.out.println(C.address);
} }
class B { public int n1 100; public static int n2 200; } class C { public static String address “北京”; } 10. 1.9 类方法基本介绍 10 类方法的调用 11 类方法应用案例 StaticMethod.java 代码:
package com.hspedu.static_;
public class StaticMethod {
public static void main(String[] args) { //创建 2 个学生对象叫学费 Stu tom new Stu(“tom”); //tom.payFee( 100); Stu.payFee( 100);//对不对?对
Stu mary new Stu(“mary”); //mary.payFee(200); Stu.payFee(200);//对
//输出当前收到的总学费 Stu.showFee();//300
//如果我们希望不创建实例也可以调用某个方法(即当做工具来使用) //这时把方法做成静态方法时非常合适 System.out.println(“9 开平方的结果是” Math.sqrt(9));
System.out.println(MyTools.calSum( 10, 30)); } } //开发自己的工具类时可以将方法做成静态的方便调用 class MyTools { //求出两个数的和 public static double calSum(double n1, double n2) {
return n1 n2; } //可以写出很多这样的工具方法… } class Stu { private String name;//普通成员 //定义一个静态变量来累积学生的学费 private static double fee 0;
public Stu(String name) { this.name name; } //说明 //1. 当方法使用了 static 修饰后该方法就是静态方法 //2. 静态方法就可以访问静态属性/变量 public static void payFee(double fee) { Stu.fee fee;//累积到 } public static void showFee() { System.out.println(“总学费有:” Stu.fee); } } 10. 1. 12 类方法经典的使用场景 13 类方法使用注意事项和细节讨论 StaticMethodDetail.java
代码:
package com.hspedu.static_;
public class StaticMethodDetail { public static void main(String[] args) {
D.hi();//ok //非静态方法不能通过类名调用 //D.say();, 错误需要先创建对象再调用 new D().say();//可以
} } class D {
private int n1 100; private static int n2 200; public void say() {//非静态方法,普通方法 }
public static void hi() {//静态方法,类方法 //类方法中不允许使用和对象有关的关键字 //比如 this 和 super 。普通方法(成员方法)可以。 //System.out.println(this.n1); }
//类方法(静态方法)中 只能访问 静态变量 或静态方法 //口诀:静态方法只能访问静态成员. public static void hello() { System.out.println(n2); System.out.println(D.n2); //System.out.println(this.n2);不能使用 hi();//OK //say();//错误 } //普通成员方法既可以访问 非静态成员也可以访问静态成员
//小结: 非静态方法可以访问 静态成员和非静态成员 public void ok() { //非静态成员 System.out.println(n1); say(); //静态成员 System.out.println(n2); hello();
} } 14 课堂练习 StaticExercise01.java 15 题 2(评讲) 看看下面代码有没有错误,如果有错误就修改看看输出什么? 代码:
class Person { //StaticExercise02.java 2min 时间 private int id;
private static int total 0; public static int getTotalPerson() { //id;//错误, 注销
return total; } public Person() {//构造器 total; //total 1 id total;//id 1 } } public class TestPerson { public static void main(String[] args) { System.out.println(Number of total is Person.getTotalPerson()); //0 Person p1 new Person(); System.out.println( Number of total is Person.getTotalPerson()); //1 } } 10. 1. 16 题 3(评讲) 看看下面代码有没有错误,如果有错误就修改看看 total 等于多少 4? 代码:
class Person { //StaticExercise03.java 2min 看 private int id; private static int total 0; public static void setTotalPerson(int total){
// this.total total;//错误因为在 static 方法中不可以使用 this 关键字
Person.total total; } public Person() {//构造器 total; id total; }} public class TestPerson { public static void main(String[] args) { Person.setTotalPerson(3); new Person(); //最后 total 的值就是 4 } } 小结记住两句话 ( 1) 静态方法只能访问静态成员 (2) 非静态方法可以访问所有的成员 (3) 在编写代码时仍然要遵守访问权限规则 10.2 理解 main 方法语法 10.2. 1 深入理解 main 方法
10.2.2 特别提示
在 main()方法中我们可以直接调用 main 方法所在类的静态方法或静态属性。但是不能直接访问该类中的非静态成员必须创建该类的一个实例对象后才能通过这个对象去访问类中的非静 态成员[举例说明] Main01.java代码
package com.hspedu.main_; public class Main01 {
//静态的变量/属性 private static String name “韩顺平教育”; //非静态的变量/属性 private int n1 10000;
//静态方法 public static void hi() { System.out.println(“Main01 的 hi 方法”);
} //非静态方法 public void cry() { System.out.println(“Main01 的 cry 方法”); }
public static void main(String[] args) {
//可以直接使用 name //1. 静态方法 main 可以访问本类的静态成员 System.out.println(“name” name); hi(); //2. 静态方法 main 不可以访问本类的非静态成员 //System.out.println(“n1” n1);//错误 //cry(); //3. 静态方法 main 要访问本类的非静态成员需要先创建对象 , 再调用即可 Main01 main01 new Main01(); System.out.println(main01.n1);//ok main01.cry(); } } 10.2.3 案例演示
10.3 代码块
10.3. 1 基本介绍
10.3.2 基本语法
10.3.3 代码块的好处和案例演示
代码:
package com.hspedu.codeblock_;
public class CodeBlock01 { public static void main(String[] args) {
Movie movie new Movie(“你好李焕英”); System.out.println(“”); Movie movie2 new Movie(“唐探 3”, 100, “陈思诚”); }
}
class Movie { private String name; private double price; private String director;
//3 个构造器- 》重载 //老韩解读 //(1) 下面的三个构造器都有相同的语句 //(2) 这样代码看起来比较冗余 //(3) 这时我们可以把相同的语句放入到一个代码块中即可 //(4) 这样当我们不管调用哪个构造器创建对象都会先调用代码块的内容 //(5) 代码块调用的顺序优先于构造器… { System.out.println(“电影屏幕打开…”); System.out.println(“广告开始…”); System.out.println(“电影正是开始…”); };
public Movie(String name) { System.out.println(“Movie(String name) 被调用…”); this.name name; }
public Movie(String name, double price) {
this.name name; this.price price; }
public Movie(String name, double price, String director) {
System.out.println(“Movie(String name, double price, String director) 被调用…”); this.name name; this.price price; this.director director; } }
10.3.4 代码块使用注意事项和细节讨论 CodeBlockDetail01.java
代码:
package com.hspedu.codeblock_; public class CodeBlockDetail01 { public static void main(String[] args) { //类被加载的情况举例 //1. 创建对象实例时(new) // AA aa new AA(); //2. 创建子类对象实例父类也会被加载, 而且父类先被加载子类后被加载 // AA aa2 new AA(); //3. 使用类的静态成员时(静态属性静态方法) // System.out.println(Cat.n1); //static 代码块是在类加载时执行的而且只会执行一次. // //
} } DD dd new DD(); DD dd1 new DD(); //普通的代码块在创建对象实例时会被隐式的调用。 // 被创建一次就会调用一次。 // 如果只是使用类的静态成员时普通代码块并不会执行 System.out.println(DD.n1);//8888, 静态模块块一定会执行 class DD { public static int n1 8888;//静态属性 //静态代码块 static { System.out.println(“DD 的静态代码 1 被执行…”);// } //普通代码块, 在 new 对象时被调用而且是每创建一个对象就调用一次
//可以这样简单的理解 普通代码块是构造器的补充 { System.out.println(“DD 的普通代码块…”); } } class Animal { //静态代码块 static { System.out.println(“Animal 的静态代码 1 被执行…”);// } } class Cat extends Animal { public static int n1 999;//静态属性 //静态代码块 static { System.out.println(“Cat 的静态代码 1 被执行…”);// } } class BB { //静态代码块 static { System.out.println(“BB 的静态代码 1 被执行…”);//1 } } class AA extends BB { //静态代码块
static { System.out.println(“AA 的静态代码 1 被执行…”);//2 } }
代码:
package com.hspedu.codeblock_;
public class CodeBlockDetail02 { public static void main(String[] args) { A a new A();// (1) A 静态代码块 01 (2) getN1 被调用…(3)A 普通代码块 01(4)getN2 被调用…(5)A() 构造器被调 用 } }
class A { { //普通代码块
System.out.println(“A 普通代码块 01”); } private int n2 getN2();//普通属性的初始化
static { //静态代码块 System.out.println(“A 静态代码块 01”); }
//静态属性的初始化 private static int n1 getN1(); public static int getN1() { System.out.println(“getN1 被调用…”); return 100; } public int getN2() { //普通方法/非静态方法 System.out.println(“getN2 被调用…”); return 200; } //无参构造器 public A() { System.out.println(“A() 构造器被调用”); } }
代码
package com.hspedu.codeblock_;
public class CodeBlockDetail03 { public static void main(String[] args) { new BBB();//(1)AAA 的普通代码块(2)AAA() 构造器被调用(3)BBB 的普通代码块(4)BBB() 构造器被调用 } }
class AAA { //父类 Object { System.out.println(“AAA 的普通代码块”); } public AAA() { //(1)super() //(2)调用本类的普通代码块 System.out.println(“AAA() 构造器被调用…”); }
}
class BBB extends AAA { { System.out.println(“BBB 的普通代码块…”); } public BBB() { //(1)super() //(2)调用本类的普通代码块 System.out.println(“BBB() 构造器被调用…”); } }
代码:
package com.hspedu.codeblock_;
public class CodeBlockDetail04 { public static void main(String[] args) { //老师说明 //(1) 进行类的加载 //1. 1 先加载 父类 A02 1.2 再加载 B02 //(2) 创建对象 //2. 1 从子类的构造器开始 //new B02();//对象
new C02(); } }
class A02 { //父类 private static int n1 getVal01(); static { System.out.println(“A02 的一个静态代码块…”);//(2) } { System.out.println(“A02 的第一个普通代码块…”);//(5) } public int n3 getVal02();//普通属性的初始化 public static int getVal01() { System.out.println(“getVal01”);//(1) return 10; }
public int getVal02() { System.out.println(“getVal02”);//(6) return 10; }
public A02() {//构造器 //隐藏 //super() //普通代码和普通属性的初始化… System.out.println(“A02 的构造器”);//(7) } }
class C02 { private int n1 100; private static int n2 200;
private void m1() {
} private static void m2() { }
static { //静态代码块只能调用静态成员 //System.out.println(n1);错误 System.out.println(n2);//ok //m1();//错误 m2(); } { //普通代码块可以使用任意成员 System.out.println(n1); System.out.println(n2);//ok m1(); m2(); } }
class B02 extends A02 { //
private static int n3 getVal03();
static { System.out.println(“B02 的一个静态代码块…”);//(4) } public int n5 getVal04(); { System.out.println(“B02 的第一个普通代码块…”);//(9)
}
public static int getVal03() { System.out.println(“getVal03”);//(3) return 10; }
public int getVal04() { System.out.println(“getVal04”);//(8) return 10; } //一定要慢慢的去品… public B02() {//构造器 //隐藏了 //super() //普通代码块和普通属性的初始化… System.out.println(“B02 的构造器”);//(10) // TODO Auto-generated constructor stub } }
10.3.5 课堂练习题 CodeBlockExercise01.java
题 1 下面的代码输出什么1min class Person { public static int total;//静态变量
static {//静态代码块 total 100; System.out.println(“in static block!”);//(1) } } public class Test { public static void main(String[] args) { System.out.println(total Person.total); //100 System.out.println(total Person.total); //100 } } 10.3.6 题 2下面的代码输出什么
题 2 下面的代码输出什么CodeBlockExercise02.java class Sample { Sample(String s) { System.out.println(s); } Sample() { System.out.println(“Sample 默认构造函数被调用); } } //
class Test{ Sample sam1new Sample(“sam1 成员初始化”);// static Sample samnew Sample(静态成员 sam 初始化 );// static { System.out.println(“static 块执行”);// if(samnull)System.out.println(“sam is null”); } Test()//构造器 { System.out.println(“Test 默认构造函数被调用”);// } } //主方法 public static void main(String str[]) { Test anew Test();//无参构造器 } //运行结果 输出什么内容并写出. 2min 看看
静态成员 sam 初始化static 块执行sam1 成员初始化Test 默认构造函数被调用
10.4 单例设计模式 10.4. 1 什么是设计模式
10.4.2 什么是单例模式
10.4.3 单例模式应用实例
代码:
package com.hspedu.single_;
public class SingleTon01 {
public static void main(String[] args) { // GirlFriend xh new GirlFriend(“小红”); // GirlFriend xb new GirlFriend(“小白”);
//通过方法可以获取对象 GirlFriend instance GirlFriend.getInstance(); System.out.println(instance);
GirlFriend instance2 GirlFriend.getInstance(); System.out.println(instance2);
System.out.println(instance instance2);//T //System.out.println(GirlFriend.n1);
//…
} }
//有一个类 GirlFriend //只能有一个女朋友 class GirlFriend {
private String name;
//public static int n1 100; //为了能够在静态方法中返回 gf 对象需要将其修饰为 static //對象通常是重量級的對象, 餓漢式可能造成創建了對象但是沒有使用. private static GirlFriend gf new GirlFriend(“小红红”);
//如何保障我们只能创建一个 GirlFriend 对象 //步骤[单例模式-饿汉式] //1. 将构造器私有化 //2. 在类的内部直接创建对象(该对象是 static) //3. 提供一个公共的 static 方法返回 gf 对象 private GirlFriend(String name) { System.out.println(“構造器被調用.”); this.name name; }
public static GirlFriend getInstance() { return gf;
}
Override public String toString() { return “GirlFriend{” “name” name ‘’’ ‘}’; }
} package com.hspedu.single_;
/**
演示懶漢式的單例模式 */ public class SingleTon02 { public static void main(String[] args) { //new Cat(“大黃”); //System.out.println(Cat.n1); Cat instance Cat.getInstance(); System.out.println(instance);
//再次調用 getInstance Cat instance2 Cat.getInstance(); System.out.println(instance2);
System.out.println(instance instance2);//T
} }
//希望在程序運行過程中只能創建一個 Cat 對象
//使用單例模式 class Cat { private String name; public static int n1 999; private static Cat cat ; //默認是 null
//步驟 //1.仍然構造器私有化 //2.定義一個 static 靜態屬性對象 //3.提供一個 public 的 static 方法可以返回一個 Cat 對象 //4.懶漢式只有當用戶使用 getInstance 時才返回 cat 對象, 後面再次調用時會返回上次創建的 cat 對象 // 從而保證了單例 private Cat(String name) { System.out.println(“構造器調用…”); this.name name; } public static Cat getInstance() {
if(cat null) {//如果還沒有創建 cat 對象 cat new Cat(“小可愛”); } return cat; }
Override public String toString() {
return “Cat{” “name” name ‘’’ ‘}’; } } 10.4.4 饿汉式 VS 懒汉式
10.5 final 关键字 10.5. 1 基本介绍
代码:
package com.hspedu.final_;
public class Final01 { public static void main(String[] args) {
E e new E(); //e.TAX_RATE 0.09; } }
//如果我们要求 A 类不能被其他类继承 //可以使用 final 修饰 A 类 final class A { } //class B extends A {}
class C { //如果我们要求 hi 不能被子类重写 //可以使用 final 修饰 hi 方法 public final void hi() {} } class D extends C { // Override // public void hi() { // System.out.println(“重写了 C 类的 hi 方法…”); // } }
//当不希望类的的某个属性的值被修改,可以用final 修饰 class E { public final double TAX_RATE 0.08;//常量
}
//当不希望某个局部变量被修改可以使用final 修饰 class F { public void cry() { //这时NUM 也称为 局部常量 final double NUM 0.01; //NUM 0.9; System.out.println(“NUM” NUM); } }
10.5.2 final 使用注意事项和细节讨论
代码:
package com.hspedu.final_;
public class FinalDetail01 {
public static void main(String[] args) { CC cc new CC();
new EE().cal(); } }
class AA { /*
定义时如 public final double TAX_RATE0.08;在构造器中在代码块中 */ public final double TAX_RATE 0.08;//1.定义时赋值 public final double TAX_RATE2 ; public final double TAX_RATE3 ;
public AA() {//构造器中赋值 TAX_RATE2 1. 1; } {//在代码块赋值 TAX_RATE3 8.8; } }
class BB {
/* 如果 final 修饰的属性是静态的则初始化的位置只能是 1 定义时 2 在静态代码块 不能在构造器中赋值。 */ public static final double TAX_RATE 99.9; public static final double TAX_RATE2 ;
static { TAX_RATE2 3.3; }
}
//final 类不能继承但是可以实例化对象 final class CC { }
//如果类不是 final 类但是含有 final 方法则该方法虽然不能重写但是可以被继承 //即仍然遵守继承的机制. class DD { public final void cal() { System.out.println(“cal()方法”); } } class EE extends DD { }
代码:
package com.hspedu.final_;
public class FinalDetail02 { public static void main(String[] args) { System.out.println(BBB.num);
//包装类,String 是 final 类不能被继承
} }
//final 和 static 往往搭配使用效率更高不会导致类加载.底层编译器做了优化处理 class BBB { public final static int num 10000; static { System.out.println(“BBB 静态代码块被执行”); }
} final class AAA{ //一般来说如果一个类已经是 final 类了就没有必要再将方法修饰成 final 方法 //public final void cry() {} } 10.5.3 final 应用实例
代码:
package com.hspedu.final_;
public class FinalExercise01 { public static void main(String[] args) { Circle circle new Circle(5.0); System.out.println(“面积” circle.calArea()); } }
class Circle { private double radius; private final double PI;// 3. 14; //构造器 public Circle(double radius) { this.radius radius; //PI 3. 14;
} { PI 3. 14; }
public double calArea() { return PI * radius * radius; } } 题 2
public int addOne(final int x) { //下面的代码是否有误为什么? 1min x; //错误,原因是不能修改 final x 的值 return x 1; //这里是可以. } }
10.6 抽象类 10.6. 1 先看一个问题 Abstract01.java
代码:
package com.hspedu.abstract_;
public class Abstract01 { public static void main(String[] args) {
} }
abstract class Animal { private String name;
public Animal(String name) { this.name name; }
//思考这里 eat 这里你实现了其实没有什么意义 //即 父类方法不确定性的问题 // 考虑将该方法设计为抽象(abstract)方法 // 所谓抽象方法就是没有实现的方法 // 所谓没有实现就是指没有方法体 // 当一个类中存在抽象方法时需要将该类声明为 abstract 类 // 一般来说抽象类会被继承有其子类来实现抽象方法. // public void eat() { // System.out.println(“这是一个动物但是不知道吃什么…”); // }
public abstract void eat() ; } 10.6.2 解决之道-抽象类快速入门
10.6.3 抽象类的介绍
10.6.4 抽象类使用的注意事项和细节讨论 AbstractDetail01.java
代码:
package com.hspedu.abstract_;
public class AbstractDetail01 { public static void main(String[] args) { //抽象类不能被实例化 //new A(); } } //抽象类不一定要包含 abstract 方法。也就是说,抽象类可以没有 abstract 方法 // 还可以有实现的方法。 abstract class A { public void hi() { System.out.println(“hi”); } } //一旦类包含了 abstract 方法,则这个类必须声明为 abstract abstract class B { public abstract void hi(); } //abstract 只能修饰类和方法不能修饰属性和其它的 class C { // public abstract int n1 1; }
10.6.5 抽象类使用的注意事项和细节讨论 AbstractDetail02.java
代码:
package com.hspedu.abstract_;
public class AbstractDetail02 { public static void main(String[] args) { System.out.println(“hello”); } } //抽象方法不能使用 private 、final 和 static 来修饰因为这些关键字都是和重写相违背的 abstract class H { public abstract void hi();//抽象方法 }
//如果一个类继承了抽象类则它必须实现抽象类的所有抽象方法除非它自己也声明为 abstract 类 abstract class E { public abstract void hi(); } abstract class F extends E {
} class G extends E { Override public void hi() { //这里相等于 G 子类实现了父类 E 的抽象方法所谓实现方法就是有方法体
} }
//抽象类的本质还是类所以可以有类的各种成员 abstract class D { public int n1 10; public static String name “韩顺平教育”; public void hi() { System.out.println(“hi”); } public abstract void hello(); public static void ok() { System.out.println(“ok”); } }
10.6.6 课堂练习题 AbstractExercise01.java 5min 练习
代码:
package com.hspedu.abstract_;
public class AbstractExercise01 { public static void main(String[] args) { //测试 Manager jack new Manager(“jack”, 999, 50000); jack.setBonus(8000); jack.work();
CommonEmployee tom new CommonEmployee(“tom”, 888, 20000); tom.work(); } }
package com.hspedu.abstract_;
abstract public class Employee { private String name; private int id; private double salary;
public Employee(String name, int id, double salary) { this.name name; this.id id; this.salary salary;
} //将 work 做成一个抽象方法 public abstract void work(); public String getName() { return name; }
public void setName(String name) { this.name name; }
public int getId() { return id; }
public void setId(int id) { this.id id; }
public double getSalary() { return salary; }
public void setSalary(double salary) { this.salary salary; }
} package com.hspedu.abstract_;
public class Manager extends Employee {
private double bonus; public Manager(String name, int id, double salary) { super(name, id, salary); }
public double getBonus() { return bonus; }
public void setBonus(double bonus) { this.bonus bonus; }
Override public void work() { System.out.println(“经理 getName() 工作中…”); } } package com.hspedu.abstract_;
public class CommonEmployee extends Employee{
public CommonEmployee(String name, int id, double salary) { super(name, id, salary); }
Override public void work() { System.out.println(“普通员工 getName() 工作中…”); } }
10.7 抽象类最佳实践-模板设计模式 10.7. 1 基本介绍
10.7.2 模板设计模式能解决的问题
10.7.3 最佳实践
代码:
package com.hspedu.abstract_;
abstract public class Template { //抽象类-模板设计模式
public abstract void job();//抽象方法
public void calculateTime() {//实现方法调用job 方法 //得到开始的时间 long start System.currentTimeMillis();
job(); //动态绑定机制 //得的结束的时间 long end System.currentTimeMillis(); System.out.println(任务执行时间 (end - start)); } } package com.hspedu.abstract_; public class AA extends Template {
//计算任务 //1… 800000 Override public void job() { //实现 Template 的抽象方法job
long num 0; for (long i 1; i 800000; i) { num i; } }
// public void job2() { // //得到开始的时间 // long start System.currentTimeMillis(); // long num 0;
// // // // // // // }
} for (long i 1; i 200000; i) { num i; } //得的结束的时间 long end System.currentTimeMillis(); System.out.println(AA 执行时间 (end - start)); package com.hspedu.abstract_; public class BB extends Template {
public void job() {//这里也去重写了 Template 的job 方法
long num 0; for (long i 1; i 80000; i) { num * i; }
} } package com.hspedu.abstract_;
public class TestTemplate { public static void main(String[] args) {
AA aa new AA(); aa.calculateTime(); //这里还是需要有良好的 OOP 基础对多态
BB bb new BB(); bb.calculateTime(); } } 10.8 接口
10.8. 1 为什么有接口
10.8.2 接口快速入门
代码:
package com.hspedu.interface_;
public interface UsbInterface { //接口 //规定接口的相关方法,老师规定的. 即规范… public void start(); public void stop(); }
package com.hspedu.interface_;
public class Camera implements UsbInterface {//实现接口,就是把接口方法实现
Override public void start() { System.out.println(“相机开始工作…”); }
Override public void stop() { System.out.println(“相机停止工作…”); } }
package com.hspedu.interface_;
//Phone 类 实现 UsbInterface //解读 1. 即 Phone 类需要实现 UsbInterface 接口 规定/声明的方法 public class Phone implements UsbInterface {
Override public void start() { System.out.println(“手机开始工作…”); }
Override public void stop() { System.out.println(“手机停止工作…”); } } package com.hspedu.interface_; public class Interface01 { public static void main(String[] args) { //创建手机相机对象 //Camera 实现了 UsbInterface Camera camera new Camera(); //Phone 实现了 UsbInterface Phone phone new Phone(); //创建计算机 Computer computer new Computer();
computer.work(phone);//把手机接入到计算机 System.out.println(“”); computer.work(camera);//把相机接入到计算机
} } 10.8.3 基本介绍
10.8.4 深入讨论
代码:
package com.hspedu.interface_;
public interface DBInterface { //项目经理
public void connect();//连接方法 public void close();//关闭连接 } package com.hspedu.interface_; //A 程序 public class MysqlDB implements DBInterface { Override public void connect() { System.out.println(“连接 mysql”);
}
Override public void close() { System.out.println(“关闭 mysql”); } } package com.hspedu.interface_;
//B 程序员连接 Oracle public class OracleDB implements DBInterface {
Override public void connect() { System.out.println(“连接 oracle”); }
Override public void close() { System.out.println(“关闭 oracle”); } } package com.hspedu.interface_;
public class Interface03 { public static void main(String[] args) {
MysqlDB mysqlDB new MysqlDB(); t(mysqlDB); OracleDB oracleDB new OracleDB(); t(oracleDB); }
public static void t(DBInterface db) { db.connect(); db.close(); } } 10.8.5 注意事项和细节
代码:
package com.hspedu.interface_;
public class InterfaceDetail01 { public static void main(String[] args) { //new IA();
} }
//1.接口不能被实例化 //2.接口中所有的方法是 public 方法, 接口中抽象方法可以不用 abstract 修饰 //3.一个普通类实现接口,就必须将该接口的所有方法都实现,可以使用 altenter 来解决 //4.抽象类去实现接口时可以不实现接口的抽象方法 interface IA { void say();//修饰符 public protected 默认 private void hi(); } class Cat implements IA{ Override public void say() { }
Override public void hi() {
} } abstract class Tiger implements IA { }
代码
package com.hspedu.interface_;
public class InterfaceDetail02 { public static void main(String[] args) { //老韩证明 接口中的属性,是 public static final System.out.println(IB.n1);//说明 n1 就是 static //IB.n1 30; 说明 n1 是 final } } interface IB { //接口中的属性, 只能是 final 的而且是 public static final 修饰符 int n1 10; //等价 public static final int n1 10; void hi(); } interface IC { void say(); }
//接口不能继承其它的类,但是可以继承多个别的接口 interface ID extends IB,IC { } //接口的修饰符 只能是 public 和默认这点和类的修饰符是一样的 interface IE{}
//一个类同时可以实现多个接口 class Pig implements IB,IC { Override public void hi() { } Override public void say() { } } 10.8.6 课堂练习
10.8.7 实现接口 vs 继承类
代码:
package com.hspedu.interface_;
public class ExtendsVsInterface { public static void main(String[] args) { LittleMonkey wuKong new LittleMonkey(“悟空”); wuKong.climbing(); wuKong.swimming(); wuKong.flying(); } }
//猴子 class Monkey {
private String name;
public Monkey(String name) { this.name name; } public void climbing() { System.out.println(name 会爬树…); }
public String getName() { return name; } }
//接口 interface Fishable { void swimming(); } interface Birdable { void flying(); }
//继承 //小结: 当子类继承了父类就自动的拥有父类的功能 // // 如果子类需要扩展功能可以通过实现接口的方式扩展. 可以理解 实现接口 是 对java 单继承机制的一种补充.
class LittleMonkey extends Monkey implements Fishable,Birdable {
public LittleMonkey(String name) { super(name); }
Override public void swimming() { System.out.println(getName() 通过学习可以像鱼儿一样游泳…); }
Override public void flying() { System.out.println(getName() 通过学习可以像鸟儿一样飞翔…); } }
10.8.8 接口的多态特性
代码:
package com.hspedu.interface_;
public class InterfacePolyParameter { public static void main(String[] args) {
//接口的多态体现 //接口类型的变量 if01 可以指向 实现了IF 接口类的对象实例 IF if01 new Monster(); if01 new Car();
//继承体现的多态 //父类类型的变量 a 可以指向 继承 AAA 的子类的对象实例 AAA a new BBB(); a new CCC(); } }
interface IF {} class Monster implements IF{} class Car implements IF{}
class AAA {
} class BBB extends AAA {} class CCC extends AAA {} package com.hspedu.interface_;
public class InterfacePolyArr { public static void main(String[] args) {
//多态数组 - 接口类型数组 Usb[] usbs new Usb[2]; usbs[0] new Phone_(); usbs[ 1] new Camera_(); /* 给 Usb 数组中存放 Phone 和 相机对象Phone 类还有一个特有的方法 call () 请遍历 Usb 数组如果是 Phone 对象除了调用 Usb 接口定义的方法外 还需要调用 Phone 特有方法 call */ for(int i 0; i usbs.length; i) {
usbs[i].work();//动态绑定… //和前面一样我们仍然需要进行类型的向下转型 if(usbs[i] instanceof Phone_) {//判断他的运行类型是 Phone_ ((Phone_) usbs[i]).call(); } }
} }
interface Usb{ void work(); } class Phone_ implements Usb { public void call() { System.out.println(“手机可以打电话…”); }
Override public void work() { System.out.println(“手机工作中…”); } } class Camera_ implements Usb {
Override
public void work() { System.out.println(“相机工作中…”); } } package com.hspedu.interface_;
/**
演示多态传递现象 */ public class InterfacePolyPass { public static void main(String[] args) { //接口类型的变量可以指向实现了该接口的类的对象实例 IG ig new Teacher(); //如果 IG 继承了 IH 接口而 Teacher 类实现了 IG 接口 //那么实际上就相当于 Teacher 类也实现了 IH 接口. //这就是所谓的 接口多态传递现象. IH ih new Teacher(); } }
interface IH { void hi(); } interface IG extends IH{ } class Teacher implements IG {
Override public void hi() { } } 10.8.9 课堂练习 InterfaceExercise02.java
package com.hspedu.interface_;
public class InterfaceExercise02 { public static void main(String[] args) {
} }
interface A { // 1min 看看 int x 0; } //想到 等价 public static final int x 0;
class B { int x 1; } //普通属性
class C extends B implements A { public void pX() { //System.out.println(x); //错误原因不明确 x
//可以明确的指定 x //访问接口的 x 就使用 A.x //访问父类的 x 就使用 super.x System.out.println(A.x super.x); }
public static void main(String[] args) { new C().pX(); } } 10.9 内部类 如果定义类在局部位置(方法中/代码块) 1) 局部内部类 (2) 匿名内部类 定义在成员位置 ( 1) 成员内部类 (2) 静态内部类 10.9. 1 基本介绍
10.9.2 基本语法
10.9.3 快速入门案例 代码:
package com.hspedu.innerclass;
public class InnerClass01 { //外部其他类 public static void main(String[] args) {
} } class Outer { //外部类 private int n1 100;//属性 public Outer(int n1) {//构造器 this.n1 n1; } public void m1() {//方法 System.out.println(“m1()”); } {//代码块 System.out.println(“代码块…”); } class Inner { //内部类, 在 Outer 类的内部
} } 10.9.4 内部类的分类
10.9.5 局部内部类的使用 LocalInnerClass.java
代码:
package com.hspedu.innerclass; /**
演示局部内部类的使用 */ public class LocalInnerClass {// public static void main(String[] args) { //演示一遍 Outer02 outer02 new Outer02(); outer02.m1(); System.out.println(“outer02 的 hashcode” outer02); } }
class Outer02 {//外部类 private int n1 100; private void m2() { System.out.println(“Outer02 m2()”); }//私有方法 public void m1() {//方法 //1.局部内部类是定义在外部类的局部位置,通常在方法 //3.不能添加访问修饰符,但是可以使用 final 修饰 //4.作用域 : 仅仅在定义它的方法或代码块中 final class Inner02 {//局部内部类(本质仍然是一个类) //2.可以直接访问外部类的所有成员包含私有的
private int n1 800; public void f1() { //5. 局部内部类可以直接访问外部类的成员比如下面 外部类 n1 和 m2() //7. 如果外部类和局部内部类的成员重名时默认遵循就近原则如果想访问外部类的成员 // 使用 外部类名.this.成员) 去访问 // 老韩解读 Outer02.this 本质就是外部类的对象, 即哪个对象调用了 m1, Outer02.this 就是哪个对象 System.out.println(“n1” n1 外部类的 n1 Outer02.this.n1); System.out.println(“Outer02.this hashcode” Outer02.this); m2(); } } //6. 外部类在方法中可以创建 Inner02 对象然后调用方法即可 Inner02 inner02 new Inner02(); inner02.f1(); } } 10.9.6 匿名内部类的使用(重要!!!)
代码:
package com.hspedu.innerclass;
/**
演示匿名内部类的使用 */ public class AnonymousInnerClass { public static void main(String[] args) { Outer04 outer04 new Outer04(); outer04.method(); } }
class Outer04 { //外部类 private int n1 10;//属性 public void method() {//方法 //基于接口的匿名内部类 //老韩解读 //1.需求 想使用 IA 接口,并创建对象 //2.传统方式是写一个类实现该接口并创建对象 //3.老韩需求是 Tiger/Dog 类只是使用一次后面再不使用 //4. 可以使用匿名内部类来简化开发 //5. tiger 的编译类型 ? IA //6. tiger 的运行类型 ? 就是匿名内部类 Outer04$1 /* 我们看底层 会分配 类名 Outer04$1
class Outer04$1 implements IA { Override public void cry() { System.out.println(“老虎叫唤…”); } } */ //7. jdk 底层在创建匿名内部类 Outer04$1,立即马上就创建了 Outer04$1 实例并且把地址 // 返回给 tiger //8. 匿名内部类使用一次就不能再使用 IA tiger new IA() { Override public void cry() { System.out.println(“老虎叫唤…”); } }; System.out.println(“tiger 的运行类型” tiger.getClass()); tiger.cry(); tiger.cry();
// // tiger.cry();
IA tiger new Tiger(); tiger.cry();
//演示基于类的匿名内部类 //分析
//1. father 编译类型 Father //2. father 运行类型 Outer04$2 //3. 底层会创建匿名内部类 /* class Outer04$2 extends Father{ Override public void test() { System.out.println(“匿名内部类重写了 test 方法”); } } */ //4. 同时也直接返回了 匿名内部类 Outer04$2 的对象 //5. 注意(“jack”) 参数列表会传递给 构造器 Father father new Father(“jack”){
Override public void test() { System.out.println(“匿名内部类重写了 test 方法”); } }; System.out.println(“father 对象的运行类型” father.getClass());//Outer04$2 father.test();
//基于抽象类的匿名内部类 Animal animal new Animal(){ Override
void eat() { System.out.println(“小狗吃骨头…”); } }; animal.eat(); } }
interface IA {//接口 public void cry(); } //class Tiger implements IA { // // Override // public void cry() { // System.out.println(“老虎叫唤…”); // } //} //class Dog implements IA{ // Override // public void cry() { // System.out.println(“小狗汪汪…”); // } //}
class Father {//类
public Father(String name) {//构造器 System.out.println(“接收到 name” name); } public void test() {//方法 } }
abstract class Animal { //抽象类 abstract void eat(); }
代码:
package com.hspedu.innerclass;
public class AnonymousInnerClassDetail {
public static void main(String[] args) {
Outer05 outer05 new Outer05(); outer05.f1(); //外部其他类—不能访问-----匿名内部类 System.out.println(“main outer05 hashcode” outer05); } }
class Outer05 { private int n1 99; public void f1() { //创建一个基于类的匿名内部类 //不能添加访问修饰符, 因为它的地位就是一个局部变量 //作用域 : 仅仅在定义它的方法或代码块中 Person p new Person(){ private int n1 88; Override public void hi() { //可以直接访问外部类的所有成员包含私有的 //如果外部类和匿名内部类的成员重名时匿名内部类访问的话 //默认遵循就近原则如果想访问外部类的成员则可以使用 (外部类名.this.成员) 去访问 System.out.println(“匿名内部类重写了 hi 方法 n1” n1 外部内的 n1 Outer05.this.n1 ); //Outer05.this 就是调用 f1 的 对象 System.out.println(“Outer05.this hashcode” Outer05.this);
} }; p.hi();//动态绑定, 运行类型是 Outer05$1
//也可以直接调用, 匿名内部类本身也是返回对象 // class 匿名内部类 extends Person {} // // // // // // // // // // new Person(){ Override public void hi() { System.out.println(“匿名内部类重写了 hi 方法,哈哈…”); } Override public void ok(String str) { super.ok(str); } }.ok(“jack”);
} }
class Person {//类 public void hi() { System.out.println(“Person hi()”); } public void ok(String str) {
System.out.println(Person ok() str); } } //抽象类/接口… 10.9.7 匿名内部类的最佳实践 当做实参直接传递简洁高效。 InnerClassExercise01.java
package com.hspedu.innerclass; import com.hspedu.abstract_.AA;
public class InnerClassExercise01 { public static void main(String[] args) {
//当做实参直接传递简洁高效 f1(new IL() { Override public void show() { System.out.println(“这是一副名画~~…”); } }); //传统方法 f1(new Picture());
}
//静态方法,形参是接口类型 public static void f1(IL il) { il.show(); } } //接口 interface IL { void show(); } //类-实现 IL 编程领域 (硬编码) class Picture implements IL {
Override public void show() { System.out.println(“这是一副名画 XX…”); } } 10.9.8 匿名内部类课堂练习
代码:
package com.hspedu.innerclass;
public class InnerClassExercise02 { public static void main(String[] args) { /* 1.有一个铃声接口 Bell 里面有个 ring 方法。(右图) 2.有一个手机类 Cellphone 具有闹钟功能 alarmClock 参数是 Bell 类型(右图) 3.测试手机类的闹钟功能通过匿名内部类(对象)作为参数打印懒猪起床了 4.再传入另一个匿名内部类(对象) 打印小伙伴上课了 */ CellPhone cellPhone new CellPhone(); //老韩解读 //1. 传递的是实现了 Bell 接口的匿名内部类 InnerClassExercise02$1 //2. 重写了 ring //3. Bell bell new Bell() { // // Override public void ring() {
// // // System.out.println(“懒猪起床了”); } } cellPhone.alarmClock(new Bell() { Override public void ring() { System.out.println(“懒猪起床了”); } });
cellPhone.alarmClock(new Bell() { Override public void ring() { System.out.println(“小伙伴上课了”); } }); } } interface Bell{ //接口 void ring();//方法 } class CellPhone{//类 public void alarmClock(Bell bell){//形参是 Bell 接口类型 System.out.println(bell.getClass()); bell.ring();//动态绑定 }
} 10.9.9 成员内部类的使用
代码
package com.hspedu.innerclass;
public class MemberInnerClass01 {
public static void main(String[] args) { Outer08 outer08 new Outer08(); outer08.t 1();
//外部其他类使用成员内部类的三种方式 //老韩解读 // 第一种方式 // outer08.new Inner08(); 相当于把 new Inner08()当做是 outer08 成员 // 这就是一个语法不要特别的纠结. Outer08.Inner08 inner08 outer08.new Inner08(); inner08.say(); // 第二方式 在外部类中编写一个方法可以返回 Inner08 对象 Outer08.Inner08 inner08Instance outer08.getInner08Instance(); inner08Instance.say();
} }
class Outer08 { //外部类 private int n1 10; public String name “张三”;
private void hi() { System.out.println(“hi()方法…”); }
//1.注意: 成员内部类是定义在外部内的成员位置上 //2.可以添加任意访问修饰符(public 、protected 、默认、private), 因为它的地位就是一个成员 public class Inner08 {//成员内部类 private double sal 99.8; private int n1 66; public void say() { //可以直接访问外部类的所有成员包含私有的 //如果成员内部类的成员和外部类的成员重名会遵守就近原则. // 可以通过 外部类名.this.属性 来访问外部类的成员 System.out.println(“n1 n1 name name 外部类的 n1” Outer08.this.n1); hi(); } } //方法返回一个 Inner08 实例 public Inner08 getInner08Instance(){ return new Inner08(); }
//写方法 public void t1() { //使用成员内部类 //创建成员内部类的对象然后使用相关的方法 Inner08 inner08 new Inner08(); inner08.say();
System.out.println(inner08.sal); } } 10.9. 10 静态内部类的使用 StaticInnerClass01.java
代码:
package com.hspedu.innerclass;
public class StaticInnerClass01 { public static void main(String[] args) { Outer10 outer10 new Outer10(); outer10.m1();
//外部其他类 使用静态内部类
//方式 1 //因为静态内部类是可以通过类名直接访问(前提是满足访问权限) Outer10.Inner10 inner10 new Outer10.Inner10(); inner10.say(); //方式 2 //编写一个方法可以返回静态内部类的对象实例. Outer10.Inner10 inner101 outer10.getInner10(); System.out.println(“”); inner101.say();
Outer10.Inner10 inner10_ Outer10.getInner10_(); System.out.println(“************”); inner10_.say(); } }
class Outer10 { //外部类 private int n1 10; private static String name “张三”; private static void cry() {} //Inner10 就是静态内部类 //1. 放在外部类的成员位置 //2. 使用 static 修饰 //3. 可以直接访问外部类的所有静态成员包含私有的但不能直接访问非静态成员 //4. 可以添加任意访问修饰符(public 、protected 、默认、private), 因为它的地位就是一个成员 //5. 作用域 同其他的成员为整个类体
static class Inner10 { private static String name “韩顺平教育”; public void say() { //如果外部类和静态内部类的成员重名时静态内部类访问的时 //默认遵循就近原则如果想访问外部类的成员则可以使用 (外部类名.成员) System.out.println(name 外部类 name Outer10.name); cry(); } }
public void m1() { //外部类—访问------静态内部类 访问方式创建对象再访问 Inner10 inner10 new Inner10(); inner10.say(); }
public Inner10 getInner10() { return new Inner10(); }
public static Inner10 getInner10_() { return new Inner10(); } } 10.9. 11 课堂测试题
public class Test {//外部类 public Test() {//构造器 Inner s1 new Inner(); s1.a 10; Inner s2 new Inner(); System.out.println(s2.a); } class Inner { //内部类成员内部类 public int a 5; }
public static void main(String[] args) { Test t new Test(); Inner r t.new Inner();//5 System.out.println(r.a);//5 } } 10. 10卖油翁和老黄牛
第 11 章枚举和注解 11. 1 先看一个需求 要求创建季节(Season) 对象请设计并完成。Enumeration01.java
class Season{//类 private String name; private String desc;//描述 //构造器 //getXX //setXX } 代码:
//package com.hspedu.enum_; ///** // * author 韩顺平 // * version 1.0 // */ //public class Enumeration01 { // public static void main(String[] args) { // //使用 // Season spring new Season(“春天”, “温暖”); // Season winter new Season(“冬天”, “寒冷”); // Season summer new Season(“夏天”, “炎热”); // Season autumn new Season(“秋天”, “凉爽”); autumn.setName(“XXX”); // // // // // // } //} autumn.setDesc(“非常的热…”); //因为对于季节而已他的对象(具体值) 是固定的四个不会有更多 //安老师的这个设计类的思路不能体现季节是固定的四个对象 //因此这样的设计不好 枚举类[枚: 一个一个 举 例举 , 即把具体的对象一个一个例举出来的类 // 就称为枚举类] Season other new Season(“红天”, “~~~”); //class Season{//类 // private String name; // private String desc;//描述 // // public Season(String name, String desc) { // this.name name; // this.desc desc; // } // // public String getName() { // return name; // } // // public void setName(String name) { // this.name name; // } // // public String getDesc() {
// // // // // // //} return desc; }
public void setDesc(String desc) { this.desc desc; } 11.2 分析问题 11.2. 1 创建 Season 对象有如下特点
季节的值是有限的几个值(spring, summer, autumn, winter)只读不需要修改。 11.3 解决方案-枚举枚举对应英文(enumeration, 简写 enum)枚举是一组常量的集合。可以这里理解枚举属于一种特殊的类里面只包含一组有限的特定的对象。 11.4 枚举的二种实现方式自定义类实现枚举使用 enum 关键字实现枚举 11.5 自定义类实现枚举-应用案例
代码:
package com.hspedu.enum_;
/**
author 韩顺平version 1.0 */ public class Enumeration02 { public static void main(String[] args) { System.out.println(Season.AUTUMN); System.out.println(Season.SPRING); } }
//演示字定义枚举实现 class Season {//类 private String name; private String desc;//描述
//定义了四个对象, 固定. public static final Season SPRING new Season(“春天”, “温暖”); public static final Season WINTER new Season(“冬天”, “寒冷”); public static final Season AUTUMN new Season(“秋天”, “凉爽”); public static final Season SUMMER new Season(“夏天”, “炎热”);
//1. 将构造器私有化, 目的防止 直接 new //2. 去掉 setXxx 方法, 防止属性被修改
//3. 在 Season 内部直接创建固定的对象 //4. 优化可以加入 final 修饰符 private Season(String name, String desc) { this.name name; this.desc desc; }
public String getName() { return name; }
public String getDesc() { return desc; }
Override public String toString() { return “Season{” “name” name ‘’’ “, desc” desc ‘’’ ‘}’; } } 11.6 自定义类实现枚举-小结 11.6. 1 小结进行自定义类实现枚举有如下特点
构造器私有化本类内部创建一组对象[四个 春夏秋冬]对外暴露对象 (通过为对象添加 public final static 修饰符)可以提供 get 方法但是不要提供 set 11.7 enum 关键字实现枚举-快速入门 11.7. 1 说明 使用 enum 来实现前面的枚举案例看老师演示主要体会和自定义类实现枚举不同的地方。Enumeration03.java 代码
package com.hspedu.enum_;
/**
author 韩顺平version 1.0 */ public class Enumeration03 { public static void main(String[] args) { System.out.println(Season2.AUTUMN); System.out.println(Season2.SUMMER); } } //演示使用 enum 关键字来实现枚举类 enum Season2 {//类
//定义了四个对象, 固定. // public static final Season SPRING new Season(“春天”, “温暖”); // public static final Season WINTER new Season(“冬天”, “寒冷”); // public static final Season AUTUMN new Season(“秋天”, “凉爽”); // public static final Season SUMMER new Season(“夏天”, “炎热”); //如果使用了 enum 来实现枚举类 //1. 使用关键字 enum 替代 class //2. public static final Season SPRING new Season(“春天”, “温暖”) 直接使用 // SPRING(“春天”, “温暖”) 解读 常量名(实参列表) //3. 如果有多个常量(对象) 使用 ,号间隔即可 //4. 如果使用 enum 来实现枚举要求将定义常量对象写在前面 //5. 如果我们使用的是无参构造器创建常量对象则可以省略 () SPRING(“春天”, “温暖”), WINTER(“冬天”, “寒冷”), AUTUMN(“秋天”, “凉爽”), SUMMER(“夏天”, “炎热”)/, What()/;
private String name; private String desc;//描述 private Season2() {//无参构造器
}
private Season2(String name, String desc) { this.name name; this.desc desc; }
public String getName() { return name; }
public String getDesc() { return desc; }
Override public String toString() { return “Season{” “name” name ‘’’ “, desc” desc ‘’’ ‘}’; } } 11.7.2 enum 关键字实现枚举注意事项 当我们使用 enum 关键字开发一个枚举类时默认会继承 Enum类, 而且是一个 final 类[如何证明],老师使用javap 工 具来演示 传统的 public static final Season2 SPRING new Season2(“春天”, “温暖”); 简化成 SPRING(“春天”, “温暖”) 这里必 须知道它调用的是哪个构造器. 如果使用无参构造器 创建 枚举对象则实参列表和小括号都可以省略 当有多个枚举对象时使用, 间隔最后有一个分号结尾 枚举对象必须放在枚举类的行首.
11.8 enum 关键字实现枚举-课堂练习 下面代码是否正确, 并说明表示的含义? enum Gender{ //1min BOY , GIRL; //这里其实就是调用 Gender 类的无参构造器 }
上面语法是 ok有一个枚举类 Gender 没有属性。有两个枚举对象 BOY, GIRL, 使用的无参构造器创建. 下面代码输出什么? EnumExercise01.java
11.9 enum 常 2 用方法说明 说明使用关键字 enum 时会隐式继承 Enum类, 这样我们就可以使用 Enum 类相关的方法。[看下源码定义.]
public abstract class EnumE extends Enum implements Comparable, Serializable { }
10enum 常用方法应用实例
我们一起来举例说明 enum 常用的方法的使用对 Season2 测试. EnumMethod.java
toString:Enum 类已经重写过了返回的是当前对象 名,子类可以重写该方法用于返回对象的属性信息name返回当前对象名 (常量名) 子类中不能重写ordinal 返回当前对象的位置号默认从 0 开始values返回当前枚举类中所有的常量valueOf将字符串转换成枚举对象要求字符串必须 为已有的常量名否则报异常compareTo比较两个枚举常量比较的就是编号代码
package com.hspedu.enum_;
/**
author 韩顺平version 1.0演示 Enum类的各种方法的使用 */ public class EnumMethod { public static void main(String[] args) { //使用 Season2 枚举类来演示各种方法 Season2 autumn Season2.AUTUMN;
//输出枚举对象的名字 System.out.println(autumn.name()); //ordinal() 输出的是该枚举对象的次序/编号从 0 开始编号
//AUTUMN 枚举对象是第三个因此输出 2 System.out.println(autumn.ordinal()); //从反编译可以看出 values 方法返回 Season2[] //含有定义的所有枚举对象 Season2[] values Season2.values(); System.out.println(“遍历取出枚举对象(增强 for)”); for (Season2 season: values) {//增强 for 循环 System.out.println(season); }
//valueOf将字符串转换成枚举对象要求字符串必须 为已有的常量名否则报异常 //执行流程 //1. 根据你输入的 “AUTUMN” 到 Season2 的枚举对象去查找 //2. 如果找到了就返回如果没有找到就报错 Season2 autumn1 Season2.valueOf(“AUTUMN”); System.out.println(“autumn1” autumn1); System.out.println(autumn autumn1);
//compareTo比较两个枚举常量比较的就是编号 //老韩解读 //1. 就是把 Season2.AUTUMN 枚举对象的编号 和 Season2.SUMMER 枚举对象的编号比较 //2. 看看结果 /* public final int compareTo(E o) {
return self.ordinal - other.ordinal; } Season2.AUTUMN 的编号[2] - Season2.SUMMER 的编号[3] */ System.out.println(Season2.AUTUMN.compareTo(Season2.SUMMER));
// // // // // // // // // // // } } //补充了一个增强 for int[] nums { 1, 2, 9}; //普通的 for 循环 System.out.println(“普通的 for”); for (int i 0; i nums.length; i) { System.out.println(nums[i]); } System.out.println(“增强的 for”); //执行流程是 依次从 nums 数组中取出数据赋给i, 如果取出完毕则退出for for(int i : nums) { System.out.println(“i” i); } 课堂完成 EnumExercise02.java
声明 Week 枚举类其中包含星期一至星期 日的定义 MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY; 使用 values 返回所有的枚举数组, 并遍历 , 输出左图效果
5min 完成
package com.hspedu.enum_;
/**
author 韩顺平version 1.0 */ public class EnumExercise02 { public static void main(String[] args) { //获取到所有的枚举对象 即数组 Week[] weeks Week.values(); //遍历使用增强 for System.out.println(“所有星期的信息如下”); for (Week week : weeks) { System.out.println(week); } } }
/* 声明 Week 枚举类其中包含星期一至星期日的定义 MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY; 使用 values 返回所有的枚举数组, 并遍历 , 输出左图效果
*/
enum Week { //定义 Week 的枚举对象 MONDAY(“星期一”), TUESDAY(“星期二”), WEDNESDAY(“星期三”), THURSDAY(“星期四”), FRIDAY(“星期五”), SATURDAY(“星期六”), SUNDAY(“星期日”); private String name;
private Week(String name) {//构造器 this.name name; }
Override public String toString() { return name; } } 11. 11enum 实现接口 EnumDetail.java
使用 enum 关键字后就不能再继承其它类了因为 enum 会隐式继承 Enum 而 Java 是单继承机制。枚举类和普通类一样可以实现接口如下形式。 enum 类名 implements 接口 1 接口 2 {}代码
package com.hspedu.enum_;
/**
author 韩顺平version 1.0 */ public class EnumDetail { public static void main(String[] args) { Music.CLASSICMUSIC.playing(); } } class A { }
//1.使用 enum 关键字后就不能再继承其它类了因为 enum 会隐式继承 Enum 而 Java 是单继承机制 //enum Season3 extends A { // //} //2.enum 实现的枚举类仍然是一个类所以还是可以实现接口的. interface IPlaying { public void playing(); } enum Music implements IPlaying { CLASSICMUSIC; Override public void playing() { System.out.println(“播放好听的音乐…”); }
} 11. 12注解的理解 注解(Annotation)也被称为元数据(Metadata) 用于修饰解释 包、类、方法、属性、构造器、局部变量等数据信息。 和注释一样注解不影响程序逻辑但注解可以被编译或运行相当于嵌入在代码中的补充信息。 在 JavaSE 中注解的使用目的比较简单例如标记过时的功能忽略警告等。在 JavaEE 中注解占据了更重要的角 色例如用来配置应用程序的任何切面代替java EE 旧版中所遗留的繁冗代码和 XML 配置等。
13基本的 Annotation 介绍 使用 Annotation 时要在其前面增加 符号, 并把该 Annotation 当成一个修饰符使用。用于修饰它支持的程序元 素 三个基本的 Annotation:
Override: 限定某个方法是重写父类方法, 该注解只能用于方法Deprecated: 用于表示某个程序元素(类, 方法等)已过时SuppressWarnings: 抑制编译器警告
14基本的 Annotation 应用案例 1 Override 注解的案例 Override_.java
package com.hspedu.annotation_;
/**
author 韩顺平version 1.0 */ public class Override_ { public static void main(String[] args) {
} } class Father{//父类 public void fly(){ System.out.println(“Father fly…”); } public void say(){} }
class Son extends Father {//子类 //老韩解读 //1. Override 注解放在 fly 方法上表示子类的 fly 方法时重写了父类的 fly //2. 这里如果没有写 Override 还是重写了父类 fly //3. 如果你写了Override 注解编译器就会去检查该方法是否真的重写了父类的 // 方法如果的确重写了则编译通过如果没有构成重写则编译错误 //4. 看看 Override 的定义 // 解读 如果发现 interface 表示一个 注解类 /* Target(ElementType.METHOD) Retention(RetentionPolicy.SOURCE) public interface Override { } */ Override //说明 public void fly() { System.out.println(“Son fly…”); } Override public void say() {} }
14.2 Deprecated 注解的案例 Deprecated_.java Deprecated: 用于表示某个程序元素(类, 方法等)已过时 代码
package com.hspedu.annotation_;
/**
author 韩顺平version 1.0 */ public class Deprecated_ { public static void main(String[] args) { A a new A(); a.hi(); System.out.println(a.n1); } }
//老韩解读 //1. Deprecated 修饰某个元素, 表示该元素已经过时 //2. 即不在推荐使用但是仍然可以使用 //3. 查看 Deprecated 注解类的源码
//4. 可以修饰方法类字段, 包, 参数 等等 //5. Deprecated 可以做版本升级过渡使用 /* Documented Retention(RetentionPolicy.RUNTIME) Target(value{CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE}) public interface Deprecated { } */ Deprecated class A { Deprecated public int n1 10; Deprecated public void hi(){
} }
14.3 SuppressWarnings 注解的案例 SuppressWarnings_.java SuppressWarnings: 抑制编译器警告
package com.hspedu.annotation_;
import java.util.ArrayList; import java.util.List;
/**
author 韩顺平version 1.0 */ SuppressWarnings({“rawtypes”, “unchecked”, “unused”}) public class SuppressWarnings_ {
//老韩解读 //1. 当我们不希望看到这些警告的时候可以使用 SuppressWarnings 注解来抑制警告信息 //2. 在{“”} 中可以写入你希望抑制(不显示)警告信息 //3. 可以指定的警告类型有 // // // // // // // // // // all 抑制所有警告 boxing 抑制与封装/拆装作业相关的警告 //cast 抑制与强制转型作业相关的警告 //dep-ann 抑制与淘汰注释相关的警告 //deprecation 抑制与淘汰的相关警告 //fallthrough 抑制与 switch 陈述式中遗漏 break 相关的警告 //finally 抑制与未传回 finally 区块相关的警告 //hiding 抑制与隐藏变数的区域变数相关的警告 //incomplete-switch 抑制与 switch 陈述式(enum case)中遗漏项目相关的警告 //javadoc 抑制与javadoc 相关的警告
// // // // // // // // // // // // // // //nls 抑制与非 nls 字串文字相关的警告 //null 抑制与空值分析相关的警告 //rawtypes 抑制与使用 raw 类型相关的警告 //resource 抑制与使用 Closeable 类型的资源相关的警告 //restriction 抑制与使用不建议或禁止参照相关的警告 //serial 抑制与可序列化的类别遗漏 serialVersionUID 栏位相关的警告 //static-access 抑制与静态存取不正确相关的警告 //static-method 抑制与可能宣告为 static 的方法相关的警告 //super 抑制与置换方法相关但不含 super 呼叫的警告 //synthetic-access 抑制与内部类别的存取未最佳化相关的警告 //sync-override 抑制因为置换同步方法而遗漏同步化的警告 //unchecked 抑制与未检查的作业相关的警告 //unqualified-field-access 抑制与栏位存取不合格相关的警告 //unused 抑制与未用的程式码及停用的程式码相关的警告 //4. 关于 SuppressWarnings 作用范围是和你放置的位置相关 // 比如 SuppressWarnings 放置在 main 方法那么抑制警告的范围就是 main // 通常我们可以放置具体的语句, 方法, 类. //5. 看看 SuppressWarnings 源码 //(1) 放置的位置就是 TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE //(2) 该注解类有数组 String[] values() 设置一个数组比如 {“rawtypes”, “unchecked”, “unused”} /* Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) Retention(RetentionPolicy.SOURCE) public interface SuppressWarnings {
String[] value();
} */ public static void main(String[] args) { List list new ArrayList(); list.add(“jack”); list.add(“tom”); list.add(“mary”); int i; System.out.println(list.get(1)); }
public void f1() { // SuppressWarnings({“rawtypes”}) List list new ArrayList();
//
} } list.add(“jack”); list.add(“tom”); list.add(“mary”); SuppressWarnings({“unused”}) int i; System.out.println(list.get(1));
15JDK 的元 Annotation(元注解 了解) 1 元注解的基本介绍 JDK 的元 Annotation 用于修饰其他 Annotation 元注解 本身作用不大讲这个原因希望同学们看源码时可以知道他是干什么. 15.2 元注解的种类 (使用不多了解, 不用深入研究)
Retention //指定注解的作用范围三种 SOURCE,CLASS,RUNTIMETarget // 指定注解可以在哪些地方使用Documented //指定该注解是否会在javadoc 体现Inherited //子类会继承父类注解
15.3 Retention 注解
说明 只能用于修饰一个 Annotation 定义, 用于指定该 Annotation 可以保留多长时间, Rentention 包含一个 RetentionPolicy 类型的成员变量, 使用 Rentention 时必须为该 value 成员变量指定值: Retention 的三种值 RetentionPolicy.SOURCE: 编译器使用后直接丢弃这种策略的注释 RetentionPolicy.CLASS: 编译器将把注解记录在 class 文件中. 当运行 Java 程序时, JVM 不会保留注解。 这是默认 值 RetentionPolicy.RUNTIME:编译器将把注解记录在 class 文件中. 当运行 Java 程序时, JVM 会保留注解. 程序可以 通过反射获取该注解 15.4 Target 15.5 Documented 15.6 Inherited 注解 16第 10 章作业
第 12 章异常-Exception 12. 1 看个实际的问题和一段代码 运行下面的代码看看有什么问题- 引出异常和异常处理机制 Exception01.java
public static void main(String[] args) { int num1 10; int num2 0; int res num1 / num2; System.out.println(“程序继续运行…”); } 12.2 解决方案-异常捕获 对异常进行捕获保证程序可以继续运行. 看老师的代码演示 try-catch
package com.hspedu.exception_;
/**
author 韩顺平version 1.0 */ public class Exception01 { public static void main(String[] args) { int num1 10; int num2 0;//Scanner(); //老韩解读
//1. num1 / num2 10 / 0 //2. 当执行到 num1 / num2 因为 num2 0, 程序就会出现(抛出)异常 ArithmeticException //3. 当抛出异常后程序就退出崩溃了 , 下面的代码就不在执行 //4. 大家想想这样的程序好吗? 不好不应该出现了一个不算致命的问题就导致整个系统崩溃 //5. java 设计者提供了一个叫 异常处理机制来解决该问题 int res num1 / num2; //如果程序员认为一段代码可能出现异常/问题可以使用 try-catch 异常处理机制来解决 //从而保证程序的健壮性 //将该代码块-选中-快捷键 ctrl alt t - 选中 try-catch //6. 如果进行异常处理那么即使出现了异常程序可以继续执行 try { int res num1 / num2; } catch (Exception e) { //e.printStackTrace(); System.out.println(“出现异常的原因” e.getMessage());//输出异常信息 }
System.out.println(“程序继续运行…”);
} } 12.3 异常介绍
12.4 异常体系图一览 12.4. 1 异常体系图
12.4.2 异常体系图的小结
12.5 常见的运行时异常 12.5. 1 常见的运行时异常包括
NullPointerException 空指针异常ArithmeticException 数学运算异常ArrayIndexOutOfBoundsException 数组下标越界异常ClassCastException 类型转换异常NumberFormatException 数字格式不正确异常[] 12.5.2 常见的运行时异常举例NullPointerException 空指针异常 NullPointerException_.java 当应用程序试图在需要对象的地方使用 null 时抛出该异常,看案例演示。
代码:
package com.hspedu.exception_;
/** author 韩顺平 version 1.0 */ public class NullPointerException_ { public static void main(String[] args) { String name null; System.out.println(name.length()); } }
ArithmeticException 数学运算异常 ArithmeticException_.java 当出现异常的运算条件时抛出此异常。例如一个整数“除以零”时抛出此类的一个实例, 案例演示
代码:
package com.hspedu.exception_;
/**
author 韩顺平version 1.0 */ public class NumberFormatException_ { public static void main(String[] args) { String name “韩顺平教育”; //将 String 转成 int
int num Integer.parseInt(name);//抛出 NumberFormatException System.out.println(num);//1234 } }
ArrayIndexOutOfBoundsException 数组下标越界异常 用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小则该索引为非法索引
代码
package com.hspedu.exception_;
/**
author 韩顺平version 1.0 */ public class ArrayIndexOutOfBoundsException_ { public static void main(String[] args) { int[] arr { 1,2,4}; for (int i 0; i arr.length; i) { System.out.println(arr[i]); }
} }
ClassCastException 类型转换异常 当试图将对象强制转换为不是实例的子类时抛出该异常。例如以下代码将生成一个 ClassCastException
代码:
package com.hspedu.exception_;
/**
author 韩顺平version 1.0 */ public class ClassCastException_ { public static void main(String[] args) { A b new B(); //向上转型 B b2 (B)b;//向下转型这里是 OK C c2 ©b;//这里抛出 ClassCastException } } class A {} class B extends A {} class C extends A {}
NumberFormatException 数字格式不正确异常 当应用程序试图将字符串转换成一种数值类型但该字符串不能转换为适当格式时抛出该异常 使用异常我们 可以确保输入是满足条件数字.
代码:
package com.hspedu.exception_;
/**
author 韩顺平version 1.0 */ public class NumberFormatException_ { public static void main(String[] args) { String name “韩顺平教育”; //将 String 转成 int int num Integer.parseInt(name);//抛出 NumberFormatException System.out.println(num);//1234 } } 12.6 编译异常
12.6. 1 介绍
12.6.2 常见的编译异常
12.6.3 案例说明
代码
package com.hspedu.exception_;
import java.io.FileInputStream; import java.io.IOException;
/**
author 韩顺平version 1.0 */ public class Exception02 { public static void main(String[] args) { try {
FileInputStream fis; fis new FileInputStream(“d:\aa.jpg”); int len; while ((len fis.read()) ! - 1) { System.out.println(len); } fis.close(); } catch (IOException e) { e.printStackTrace(); } } } 12.7 异常课堂练习 看看下面代码是否正确为什么 课堂练习4 个题 4min
12.8 异常处理
12.8. 1 基本介绍
12.8.2 异常处理的方式
12.8.3 示意图
12.9 try-catch 异常处理 12.9. 1 try-catch 方式处理异常说明 TryCatch01.java
12.9.2 try-catch 方式处理异常-快速入门 代码:
public static void main(String[] args) {
int num1 10; int num2 0; try { int res num1 / num2; } catch (Exception e) { System.out.println(e.getMessage()); } } 12.9.3 try-catch 方式处理异常-注意事项 TryCatchDetail.java
代码
package com.hspedu.try_;
/**
author 韩顺平version 1.0 */
public class TryCatchDetail { public static void main(String[] args) {
//ctrl atl t //老韩解读 //1. 如果异常发生了则异常发生后面的代码不会执行直接进入到 catch 块 //2. 如果异常没有发生则顺序执行 try 的代码块不会进入到 catch //3. 如果希望不管是否发生异常都执行某段代码(比如关闭连接释放资源等)则使用如下代码- finally try { String str “韩顺平”; int a Integer.parseInt(str); System.out.println(“数字” a); } catch (NumberFormatException e) { System.out.println(“异常信息” e.getMessage()); } finally { System.out.println(“finally 代码块被执行…”); }
System.out.println(“程序继续…”);
} }
代码
package com.hspedu.try_;
/**
author 韩顺平version 1.0 */ public class TryCatchDetail02 { public static void main(String[] args) {
//老韩解读 //1.如果 try 代码块有可能有多个异常 //2.可以使用多个 catch 分别捕获不同的异常相应处理 //3.要求子类异常写在前面父类异常写在后面 try { Person person new Person(); //person null; System.out.println(person.getName());//NullPointerException int n1 10; int n2 0; int res n1 / n2;//ArithmeticException } catch (NullPointerException e) { System.out.println(“空指针异常” e.getMessage());
} catch (ArithmeticException e) { System.out.println(“算术异常” e.getMessage()); } catch (Exception e) { System.out.println(e.getMessage()); } finally { }
} }
class Person { private String name “jack”;
public String getName() { return name; } }
代码:
package com.hspedu.try_;
/**
author 韩顺平version 1.0 */ public class TryCatchDetail03 { public static void main(String[] args) {
/* 可以进行 try-finally 配合使用, 这种用法相当于没有捕获异常 因此程序会直接崩掉/退出。应用场景就是执行一段代码不管是否发生异常 都必须执行某个业务逻辑 */ try{ int n1 10; int n2 0; System.out.println(n1 / n2); }finally { System.out.println(“执行了 finally…”); } System.out.println(“程序继续执行…”);
}
}
12.9.4 异常处理课堂练习 题 1 TryCatchExercise01.java 题 2TryCatchExercise02.java 题 3TryCatchExercise03.java
12.9.5 try-catch-finally 执行顺序小结
12.9.6 课后练习题: TryCatchExercise04.java 如果用户输入的不是一个整数就提示他反复输入直到输入一个整数为止
package com.hspedu.try_;
import java.util.Scanner;
/**
author 韩顺平version 1.0 */ public class TryCatchExercise04 { public static void main(String[] args) {
//如果用户输入的不是一个整数就提示他反复输入直到输入一个整数为止 //思路 //1. 创建 Scanner 对象 //2. 使用无限循环去接收一个输入 //3. 然后将该输入的值转成一个 int //4. 如果在转换时抛出异常说明输入的内容不是一个可以转成int 的内容 //5. 如果没有抛出异常则 break 该循环 Scanner scanner new Scanner(System.in); int num 0; String inputStr “”; while (true) {
System.out.println(“请输入一个整数:”); // inputStr scanner.next(); try { num Integer.parseInt(inputStr); //这里是可能抛出异常 break; } catch (NumberFormatException e) {
System.out.println(“你输入的不是一个整数:”); } } System.out.println(“你输入的值是” num); } } 10throws 异常处理 1 基本介绍 10.2 快速入门案例 10.3 注意事项和使用细节 ThrowsDetail.java
代码:
package com.hspedu.throws_;
import java.io.FileInputStream; import java.io.FileNotFoundException;
/**
author 韩顺平version 1.0 */ public class ThrowsDetail { public static void main(String[] args) { f2(); }
public static void f2() /throws ArithmeticException/ { //1.对于编译异常程序中必须处理比如 try-catch 或者 throws //2.对于运行时异常程序中如果没有处理默认就是throws 的方式处理
int n1 10; int n2 0; double res n1 / n2;
}
public static void f1() throws FileNotFoundException { //这里大家思考问题 调用f3() 报错 //老韩解读 //1. 因为 f3() 方法抛出的是一个编译异常 //2. 即这时就要 f1() 必须处理这个编译异常 //3. 在 f1() 中要么 try-catch-finally ,或者继续 throws 这个编译异常 f3(); // 抛出异常 } public static void f3() throws FileNotFoundException { FileInputStream fis new FileInputStream(“d://aa.txt”); }
public static void f4() { //老韩解读: //1. 在 f4()中调用方法 f5() 是 OK //2. 原因是 f5() 抛出的是运行异常 //3. 而java 中并不要求程序员显示处理, 因为有默认处理机制 f5(); } public static void f5() throws ArithmeticException {
} }
class Father { //父类 public void method() throws RuntimeException { } }
class Son extends Father {//子类 //3. 子类重写父类的方法时对抛出异常的规定:子类重写的方法 // 所抛出的异常类型要么和父类抛出的异常一致要么为父类抛出的异常类型的子类型 //4. 在 throws 过程中如果有方法 try-catch , 就相当于处理异常就可以不必 throws Override public void method() throws ArithmeticException { } } 12. 11自定义异常 12. 11. 1 基本概念 11.2 自定义异常的步骤 11.3 自定义异常的应用实例 CustomException.java
代码:
package com.hspedu.customexception_;
/**
author 韩顺平version 1.0 */ public class CustomException { public static void main(String[] args) /throws AgeException/ {
int age 180; //要求范围在 18 – 120 之间否则抛出一个自定义异常 if(!(age 18 age 120)) { //这里我们可以通过构造器设置信息 throw new AgeException(“年龄需要在 18~ 120 之间”); } System.out.println(“你的年龄范围正确.”); } } //自定义一个异常 //老韩解读 //1. 一般情况下我们自定义异常是继承 RuntimeException //2. 即把自定义异常做成 运行时异常好处时我们可以使用默认的处理机制 //3. 即比较方便
class AgeException extends RuntimeException { public AgeException(String message) {//构造器 super(message); } } 12. 12throw 和 throws 的区别 12. 12. 1 一览表 12.2 测试题-下面的测试输出什么 ThrowException.java 2min 13本章作业
第 13 章常用类 13. 1 包装类 13. 1. 1 包装类的分类 WrapperType.java
针对八种基本数据类型相应的引用类型—包装类有了类的特点就可以调用类中的方法。如图: 1.2 包装类和基本数据的转换 1.3 案例演示 Integer01.java
package com.hspedu.wrapper;
/**
author 韩顺平version 1.0 */ public class Integer01 { public static void main(String[] args) { //演示 int – Integer 的装箱和拆箱 //jdk5 前是手动装箱和拆箱 //手动装箱 int-Integer int n1 100; Integer integer new Integer(n1); Integer integer1 Integer.valueOf(n1);
//手动拆箱 //Integer - int int i integer.intValue();
//jdk5 后就可以自动装箱和自动拆箱 int n2 200; //自动装箱 int-Integer Integer integer2 n2; //底层使用的是 Integer.valueOf(n2) //自动拆箱 Integer-int int n3 integer2; //底层仍然使用的是 intValue()方法 }
} 13. 1.4 课堂测试题 WrapperExercise01.java 2min
1.5 包装类型和 String 类型的相互转换 WrapperVSString.java 案例演示, 以 Integer 和 String 转换为例其它类似:
package com.hspedu.wrapper;
/**
author 韩顺平version 1.0 */ public class WrapperVSString { public static void main(String[] args) { //包装类(Integer)-String Integer i 100;//自动装箱
//方式 1 String str1 i “”; //方式 2 String str2 i.toString(); //方式 3 String str3 String.valueOf(i);
//String - 包装类(Integer) String str4 “12345”; Integer i2 Integer.parseInt(str4);//使用到自动装箱 Integer i3 new Integer(str4);//构造器 System.out.println(“ok~~”);
} } 13. 1.6 Integer 类和 Character 类的常用方法
package com.hspedu.wrapper;
/**
author 韩顺平version 1.0 */
public class WrapperMethod { public static void main(String[] args) { System.out.println(Integer.MIN_VALUE); //返回最小值 System.out.println(Integer.MAX_VALUE);//返回最大值
System.out.println(Character.isDigit(‘a’));//判断是不是数字 System.out.println(Character.isLetter(‘a’));//判断是不是字母 System.out.println(Character.isUpperCase(‘a’));//判断是不是大写 System.out.println(Character.isLowerCase(‘a’));//判断是不是小写
System.out.println(Character.isWhitespace(‘a’));//判断是不是空格 System.out.println(Character.toUpperCase(‘a’));//转成大写 System.out.println(Character.toLowerCase(‘A’));//转成小写
} } 13. 1.7 Integer 类面试题 1 WrapperExercise02.java 看看下面代码输出什么结果? 为什么? 2min
package com.hspedu.wrapper;
/**
author 韩顺平version 1.0 */ public class WrapperExercise02 {
public static void main(String[] args) { Integer i new Integer( 1); Integer j new Integer( 1); System.out.println(i j); //False //所以这里主要是看范围 - 128 ~ 127 就是直接返回 /* 老韩解读 //1. 如果 i 在 IntegerCache.low(- 128)~IntegerCache.high(127),就直接从数组返回 //2. 如果不在 - 128~ 127,就直接 new Integer(i) public static Integer valueOf(int i) { if (i IntegerCache.low i IntegerCache.high) return IntegerCache.cache[i (-IntegerCache.low)]; return new Integer(i); } */ Integer m 1; //底层 Integer.valueOf(1); - 阅读源码 Integer n 1;//底层 Integer.valueOf(1); System.out.println(m n); //T //所以这里主要是看范围 - 128 ~ 127 就是直接返回 // 否则就 new Integer(xx); Integer x 128;//底层 Integer.valueOf(1); Integer y 128;//底层 Integer.valueOf(1); System.out.println(x y);//False
} }
1.8 Intege 类面试题总结 看看下面代码输出什么结果.WrapperExercise03.java 5min
package com.hspedu.wrapper;
/**
author 韩顺平version 1.0 */ public class WrapperExercise03 { public static void main(String[] args) { //示例一 Integer i 1 new Integer( 127); Integer i2 new Integer( 127); System.out.println(i1 i2);//F //示例二 Integer i3 new Integer( 128); Integer i4 new Integer( 128); System.out.println(i3 i4);//F
//示例三 Integer i5 127;//底层 Integer.valueOf(127) Integer i6 127;//- 128~ 127 System.out.println(i5 i6); //T //示例四 Integer i7 128;
Integer i8 128; System.out.println(i7 i8);//F //示例五 Integer i9 127; //Integer.valueOf(127) Integer i 10 new Integer( 127); System.out.println(i9 i10);//F
//示例六 Integer i 11 127; int i12 127; //只有有基本数据类型判断的是 //值是否相同 System.out.println(i11i12); //T //示例七 Integer i 13 128; int i14 128; System.out.println(i13i14);//T } } 13.2 String 类 13.2. 1 String 类的理解和创建对象
代码:
package com.hspedu.string_;
/**
author 韩顺平version 1.0 */ public class String01 { public static void main(String[] args) { //1.String 对象用于保存字符串也就是一组字符序列 //2. “jack” 字符串常量, 双引号括起的字符序列 //3. 字符串的字符使用 Unicode 字符编码一个字符(不区分字母还是汉字)占两个字节 //4. String 类有很多构造器构造器的重载
// 常用的有 String s1 new String(); // //String s2 new String(String original); //String s3 new String(char[] a); //String s4 new String(char[] a,int startIndex,int count) //String s5 new String(byte[] b) //5. String 类实现了接口 Serializable【String 可以串行化:可以在网络传输】 // 接口 Comparable [String 对象可以比较大小] //6. String 是 final 类不能被其他的类继承 //7. String 有属性 private final char value[]; 用于存放字符串内容 //8. 一定要注意value 是一个 final 类型 不可以修改(需要功力)即 value 不能指向 // 新的地址但是单个字符内容是可以变化
String name “jack”; name “tom”; final char[] value {‘a’,‘b’,‘c’}; char[] v2 {‘t’,‘o’,‘m’}; value[0] ‘H’; //value v2; 不可以修改 value 地址
} } 13.2.2 创建 String 对象的两种方式
13.2.3 两种创建 String 对象的区别
13.2.4 课堂测试题 StringExercise01.java
对应的示意图:
13.3 字符串的特性 13.3. 1 说明 StringExercise06.java
13.3.2 面试题
13.4 String 类的常见方法 13.4. 1 说明
13.4.2 String 类的常见方法一览
代码:
package com.hspedu.string_;
/**
author 韩顺平version 1.0 */ public class StringMethod01 { public static void main(String[] args) { //1. equals 前面已经讲过了. 比较内容是否相同区分大小写 String str1 “hello”;
String str2 “Hello”; System.out.println(str1.equals(str2));//
// 2.equalsIgnoreCase 忽略大小写的判断内容是否相等 String username “johN”; if (“john”.equalsIgnoreCase(username)) { System.out.println(“Success!”); } else { System.out.println(“Failure!”); } // 3.length 获取字符的个数字符串的长度 System.out.println(“韩顺平”.length()); // 4.indexOf 获取字符在字符串对象中第一次出现的索引索引从 0 开始如果找不到返回- 1 String s1 “werterweg”; int index s1.indexOf(‘’); System.out.println(index);// 3 System.out.println(“weIndex” s1.indexOf(“we”));//0 // 5.lastIndexOf 获取字符在字符串中最后一次出现的索引索引从 0 开始如果找不到返回- 1 s1 “werterweg”; index s1.lastIndexOf(‘’); System.out.println(index);//11 System.out.println(“ter 的位置” s1.lastIndexOf(“ter”));//4 // 6.substring 截取指定范围的子串 String name “hello,张三”; //下面 name.substring(6) 从索引 6 开始截取后面所有的内容 System.out.println(name.substring(6));//截取后面的字符
//name.substring(0,5)表示从索引 0 开始截取截取到索引 5- 14 位置 System.out.println(name.substring(2,5));//llo
} }
package com.hspedu.string_;
/**
author 韩顺平version 1.0 */ public class StringMethod02 { public static void main(String[] args) { // 1.toUpperCase 转换成大写 String s “heLLo”; System.out.println(s.toUpperCase());//HELLO // 2.toLowerCase
System.out.println(s.toLowerCase());//hello // 3.concat 拼接字符串 String s1 “宝玉”; s1 s1.concat(“林黛玉”).concat(“薛宝钗”).concat(“together”); System.out.println(s1);//宝玉林黛玉薛宝钗 together // 4.replace 替换字符串中的字符 s1 “宝玉 and 林黛玉 林黛玉 林黛玉”; //在 s1 中将 所有的 林黛玉 替换成薛宝钗 // 老韩解读: s1.replace() 方法执行后返回的结果才是替换过的. // 注意对 s1 没有任何影响 String s11 s1.replace(“宝玉”, “jack”); System.out.println(s1);//宝玉 and 林黛玉 林黛玉 林黛玉 System.out.println(s11);//jack and 林黛玉 林黛玉 林黛玉 // 5.split 分割字符串, 对于某些分割字符我们需要 转义比如 | \等 String poem “锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦”; //老韩解读 // 1. 以 , 为标准对 poem 进行分割 , 返回一个数组 // 2. 在对字符串进行分割时如果有特殊字符需要加入 转义符 String[] split poem.split(“,”); poem “E:\aaa\bbb”; split poem.split(“\\”); System.out.println(“分割后内容”); for (int i 0; i split.length; i) { System.out.println(split[i]); } // 6.toCharArray 转换成字符数组
s “happy”; char[] chs s.toCharArray(); for (int i 0; i chs.length; i) { System.out.println(chs[i]); } // 7.com