目录
第一章 Java概述
1.1 什么是程序
1.2 Java 技术体系平台
1.3 Java 重要特点
1.4 Java 的开发工具
4.1 工具选择
1.5 Java 运行机制及运行过程
5.1 Java 语言的特点:跨平台性
5.2 Java 核心机制-Java 虚拟机 [JVMjavavirtual machine]
1.6 什么是JDK,JRE
6.1 JDK 基本介绍
6.2 JRE 基本介绍
6.3 JDK、JRE 和 JVM的包含关系
1.7 Java 快速入门
1 需求说明
2 开发步骤
3运行原理示意图
1.8. Java开发快速入门
1.9. Java 开发注意事项和细节说明
1.10 Java 转义字符
1. Java 常用的转义字符
1.11. 注释(comment)
1 Java 中的注释类型
3 使用细节
4 文档注释:
1.12 Java 代码规范
1.13 DOS 命令(了解)
1. DOS 介绍
2 相关的知识补充: 相对路径, 绝对路径
3 常用的dos命令
第二章 变量
2.1 为什么需要变量
2.2 变(变化)量(值)的介绍
2.1概念
2.2变量使用的基本步骤
2.3 程序中 +号的使用
2.4 数据类型
4.1 整数类型
4.1.1 案例演示:
4.1.2 整型的类型
4.1.3 整型的使用细节 IntDetail.java
4.2 浮点类型
4.2.1 基本介绍
4.2.2 浮点型的分类
4.3 字符类型(char)
4.3.1 基本介绍
4.3.2 案例演示 Char01.java
4.3.3 字符类型使用细节
4.4 布尔类型:boolean
4.5 基本数据类型转换
4.5.1 自动类型转换
4.5.2 自动类型转换注意和细节
4.5.3 强制类型转换
4.5.4 强制类型转换细节说明
4.5.5 基本数据类型转换-练习题
4.6 基本数据类型和String类型的转换
4.6.1 介绍和使用
4.6.2 注意事项
4.7 本章作业
第三章 运算符
3.1 运算符介绍
3.1.1 运算符介绍
3.2 算术运算符
3.2.1 案例演示
3.2.2 细节说明
3.2.3 面试题
3.3 关系运算符(比较运算符)
3.4 逻辑运算符
3.4.1 介绍
3.4.2 &&和&基本规则:
3.4.3 &&和&案例演示
3.4.4 && 和 & 使用区别
3.4.5 ||和|基本规则
3.4.6 ||和|案例演示
3.4.7 ||和|使用区别
3.4.8 !取反基本规则
3.4.9 !案例演示
3.4.10 ^案例演示
3.4.11 练习题1请写出每题的输出结果
3.4.12 练习题2请写输出结果
3.5 赋值运算符
3.6 三元运算符
3.6.1 案例演示
3.6.2 使用细节
3.7 运算符优先级
3.8 标识符的命名规则和规范
3.8.1 标识符命名规范[更加专业]
3.9 关键字
3.10 保留字
3.11 键盘输入语句
3.12 进制(程序员的基本功)
3.12.1 进制介绍
3.13 进制的图示
3.14 进制的转换(基本功)
3.15 二进制在运算中的说明
3.16 原码、反码、补码(重点 难点)
3.17 位运算符
第四章 程序控制结构
4..1 程序流程控制介绍
4.2 顺序控制
4.3 分支控制if-else
4.4 switch 分支结构
4.4.1 基本语法:
4.4.2 流程图
4.4.3 switch注意事项和细节讨论
4.4.4 switch 和 if 的比较
4.5 for循环控制 (!!!)
4.5.1 基本语法
4.5.2 for 循环执行流程分析
4.5.3 for循环练习题
4.6 while循环控制
4.6.1 基本语法
4.6.2 while循环执行流程分析
4.7 do..while循环控制
4.7.1 基本语法
4.7.2 说明:
4.7.3 画出流程图:
4.7.4 注意事项和细节说明
4.8 多重循环控制 (难点! 重点!)
4.8.1 介绍
4.9 跳转控制语句-break
4.9.1 基本介绍:
4.9.2 基本语法:
4.9.3 以 while 使用break 为例,画出示意图
4.9.4 快速入门:
4.9.5 注意事项和细节说明:
4.10 跳转控制语句-continue
4.10.1 基本介绍:
4.10.2 基本语法:
4.10.3 以 while 使用continue 为例,画出示意图
4.10.4 快速入门案例
4.11 跳转控制语句-return
第五章数组、排序和查找
5.1 数组介绍
5.2 数组的使用
5.2.1 使用方式2-动态初始化
5.2.2 使用方式3-静态初始化
5.3 数组使用注意事项和细节
5.4 数组赋值机制
5.5 数组拷贝
5.7 数组反转
5.8 数组添加/扩容
5.9 排序的介绍
5.9.1 内部排序:
5.9.2 外部排序法:
5.10 冒泡排序法
5.11 查找
5.12 多维数组-二维数组
5.12.1 快速入门案例
5.12.2 使用方式1:动态初始化
5.12.3 使用方式2: 动态初始化
5.12.4 使用方式3: 动态初始化-列数不确定
5.12.5 使用方式4:静态初始化
5.13 二维数组使用细节和注意事项
5.14 二维数组练习
第六章面向对象编程(基础部分)
6.1 类与对象
6.1.1 类和对象的区别和联系
6.1.2 属性/成员变量/字段
6.1.3 如何创建对象
6.1.4 如何访问属性
6.1.5 类和对象的内存分配机制
6.2 成员方法
6.2.1 基本介绍
6.2.2 成员方法快速入门
6.2.3 方法的调用机制原理:(重要!-示意图!!!)
6.2.4 成员方法的好处
6.2.5 成员方法的定义
6.2.6 注意事项和使用细节
6.2.7 类定义的完善
6.3 成员方法传参机制(非常非常重要)
6.3.1 基本数据类型的传参机制
6.3.2 引用数据类型的传参机制
6.4 方法递归调用(非常非常重要,比较难)
6.4.1 基本介绍
6.4.2 递归能解决什么问题?
6.4.3 递归举例
6.4.4递归重要规则
6.5 方法重载(OverLoad)
6.5.1基本介绍
6.5.2 重载的好处
6.5.3 快速入门案例
6.5.4 注意事项和使用细节
6.5.5 课堂练习题
6.6 可变参数
6.6.1 基本概念
6.6.2 基本语法
6.6.3 快速入门案例
6.6.4 注意事项和使用细节
6.7 作用域
6.7.1 基本使用
6.7.2 注意事项和细节使用
6.8 构造方法/构造器
6.8.1 看一个需求
6.8.2 基本语法
6.8.3 基本介绍
6.8.4 快速入门
6.8.5 注意事项和使用细节
6.9 对象创建的流程分析
6.9.1 看一个案例
6.10 this 关键字
6.10.1 先看一段代码,并分析问题
6.10.2 深入理解this
6.10.3 this 的注意事项和使用细节
第 七 章 面向对象编程(中级部分)
7.1 工具介绍
7.2 包
7.2.1 看一个应用场景
7.2.2 包的三大作用
7.2.3 包基本语法
7.2.4 包的本质分析(原理)
7.2.5 快速入门
7.2.6 包的命名
7.2.7 常用的包
7.2.8 如何引入包
7.2.9 注意事项和使用细节
7.3 访问修饰符
7.3.1 基本介绍
7.3.2 使用的注意事项
7.4 面向对象编程三大特征
7.5 封装
7.5.1 封装介绍
7.5.2 封装的理解和好处
7.5.3 封装的实现步骤 (三步)
7.5.4 快速入门案例
7.6 面向对象编程-继承
7.6.1 为什么需要继承
7.6.2 继承基本介绍和示意图
7.6.3 继承的基本语法
7.6.4 快速入门案例
7.6.5 继承给编程带来的便利
7.6.6 继承的深入讨论/细节问题
7.7 super关键字
7.7.1 介绍:
7.7.2 super 给编程带来的便利/细节
7.7.3 super 和 this 的比较
7.8 方法重写/覆盖(override)
7.8.1 基本介绍
代码案例:
7.8.2 注意事项和使用细节
7.9 面向对象编程-多态
7.9.1 多[多种]态[状态]基本介绍
7.9.2 多态的具体体现
7.9.3 多态注意事项和细节讨论
7.9.4 java 的动态绑定机制(非常非常重要.)
7.9.5 多态的应用
7.10 Object类详解
7.10.1 equals方法
7.10.2 如何重写equals方法
7.10.3 hashCode 方法
7.10.4 toString方法
7.10.5 finalize方法
7.11 断点调试(debug)
7.11.1 一个实际需求
7.11.2 断点调试介绍
7.11.3 断点调试的快捷键
第一章 Java概述
1.1 什么是程序
程序:计算机执行某些操作或解决某个问题而编写的一系列有序指令的集合
1.2 Java 技术体系平台
1.3 Java 重要特点
1) Java 语言是面向对象的(oop)
2) Java 语言是健壮的。Java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证
3) Java 语言是跨平台性的。[即: 一个编译好的.class 文件可以在多个系统下运行,这种特性称为跨平台]
4) Java 语言是解释型的[了解]
解释性语言:javascript,PHP, java 编译性语言:c/c++
区别是:解释性语言,编译后的代码,不能直接被机器执行,需要解释器来执行, 编译性语言, 编译后的代码, 可以直接被机器执行,c/c++
1.4 Java 的开发工具
4.1 工具选择
如何选择开发工具:
我们先选择用文本编辑器本sublime,到大家对java有一定了解后,我们再使用IDEA 和 Eclipse开发工具。
这是为什么呢:
更深刻的理解java技术,培养代码感。【面试时,往往程序员手写代码】 有利于公司面试。
1.5 Java 运行机制及运行过程
5.1 Java 语言的特点:跨平台性
5.2 Java 核心机制-Java 虚拟机 [JVMjavavirtual machine]
基本介绍:
1.JVM是一个虚拟的计算机,具有指令集并使用不同的存储区域。负责执行指令,管理数据、内存、寄存器,包含在JDK 中
2.对于不同的平台,有不同的虚拟机。
3.Java 虚拟机机制屏蔽了底层运行平台的差别,实现了“一次编译,到处运行”[说明]
示意图
1.6 什么是JDK,JRE
6.1 JDK 基本介绍
1. JDK 的全称(JavaDevelopment Kit Java 开发工具包)
JDK =JRE+java 的开发工具 [java,javac,javadoc,javap 等]
2. JDK是提供给Java开发人员使用的,其中包含了java的开发工具,也包括了JRE。所以安装了JDK,就不用在单独 安装JRE了。
6.2 JRE 基本介绍
1.JRE(Java Runtime Environment Java 运行环境)
JRE =JVM+Java 的核心类库[类]
2. 包括Java虚拟机(JVMJavaVirtual Machine)和 Java 程序所需的核心类库等,如果想要运行一个开发好的Java程序, 计算机中只需要安装JRE即可。
6.3 JDK、JRE 和 JVM的包含关系
1. JDK=JRE+ 开发工具集(例如Javac,java编译工具等)
2. JRE=JVM+JavaSE标准类库(java核心类库)
3. 如果只想运行开发好的 .class文件 只需要JRE
1.7 Java 快速入门
1 需求说明
要求开发一个Hello.java程序,可以输出"hello,world!"
2 开发步骤
1)将Java代码编写到扩展名为Hello.java的文件中。[代码说明]
2)通过javac命令对该java文件进行编译,生成.class文件。
3)通过java命令对生成的class文件进行运行。
3运行原理示意图
1.8 Java 开发注意事项和细节说明
1.10 Java 转义字符
1. Java 常用的转义字符
在控制台,输入tab键,可以实现命令补全
\t :一个制表位,实现对齐的功能
\n :换行符
\\ :一个\
\" :一个'
\r :一个回车 System.out.println("java学习\r 北京");
1.11. 注释(comment)
用于注解说明解释程序的文字就是注释,注释提高了代码的阅读性(可读性);注释是一个程序员必须要具有的良 好编程习惯。将自己的思想通过注释先整理出来,再用代码去体现。 [举例]
1 Java 中的注释类型
1) 单行注释 //
2) 多行注释 /**/
3) 文档注释 /** */
1. 单行注释: 基本格式 格式: //注释文字
2 多行注释: 基本格式 格式: /* 注释文字 */
3 使用细节
1) 被注释的文字,不会被JVM(java虚拟机)解释执行
2) 多行注释里面不允许有多行注释嵌套
4 文档注释:
1.12 Java 代码规范
1.13 DOS 命令(了解)
1. DOS 介绍
Dos: Disk Operating System 磁盘操作系统, 简单说一下windows的目录结构。[原理图]
2 相关的知识补充: 相对路径, 绝对路径
3 常用的dos命令
1) 查看当前目录是有什么内容 dir
dir dir d:\abc2\test200
2) 切换到其他盘下:盘符号 cd:changedirectory
案例演示:切换到 c盘 cd/D c:
3) 切换到当前盘的其他目录下 (使用相对路径和绝对路径演示), ..\表示上一级目录
案例演示: cd d:\abc2\test200 cd..\..\abc2\test200
4) 切换到上一级:
案例演示: cd..
5) 切换到根目录:cd\
案例演示:cd\
6) 查看指定的目录下所有的子级目录 tree
7) 清屏 cls
8) 退出DOS exit
9) 说明: 因为小伙伴后面使用DOS 非常少,所以对下面的几个指令,给大家演示下, 大家了解即可 (md[创建目 录],rd[删除目录],copy[拷贝文件],del[删除文件],echo[输入内容到文件],type,move[剪切]) => Linux。
第二章 变量
2.1 为什么需要变量
1.1一个程序就是一个世界
1.2变量是程序的基本组成单位
1.3简单的原理示意图
2.2 变(变化)量(值)的介绍
2.1概念
变量相当于内存中一个数据存储空间的表示,你可以把变量看做是一个房间的门牌号,通过门牌号我们可以找到房间,而通过变量名可以访问到变量(值)。
2.2变量使用的基本步骤
1) 声明变量
int a;
2) 赋值
a =60; //应该这么说: 把60赋给a
使用 System.out.println(a);
//也可以一步到位[inta=60;通常我们是一步完成]
2.3 程序中 +号的使用
2.4 数据类型
每一种数据都定义了明确的数据类型,在内存中分配了不同大小的内存空间(字节)。
上图说
1.java数据类型分为两大类基本数据类型,引用类型
2.基本数据类型有8中数值型[byte,short,int,long,float,double]char,boolean
3.引用类型[类,接口,数组]
4.1 整数类型
Java的整数类型就是用于存放整数值的,比如12,30,3456等等
4.1.1 案例演示:
byten1=10;
shortn2=10;
intn3=10;//4个字节
longn4=10;//8个字节
4.1.2 整型的类型
4.1.3 整型的使用细节 IntDetail.java
publicclassIntDetail{//编写一个main方法
publicstaticvoidmain(String[]args){//Java的整型常量(具体值)默认为int型,声明long型常量须后加‘l’或‘L’intn1=1;//4个字节
//intn2=1L;//对不对?不对
longn3=1L;//对}}
4.2 浮点类型
4.2.1 基本介绍
Java 的浮点类型可以表示一个小数,比如 123.4 ,7.8 ,0.12等等
4.2.2 浮点型的分类
4.3 字符类型(char)
4.3.1 基本介绍
字符类型可以表示单个字符,字符类型是char,char是两个字节(可以存放汉字),多个字符我们用字符串String
4.3.2 案例演示 Char01.java
#代码
char c1 = 'a';
char c2 = '\t';
char c3 = '学习';
char c4 = 97;
4.3.3 字符类型使用细节
4.4 布尔类型:boolean
4.5 基本数据类型转换
4.5.1 自动类型转换
4.5.2 自动类型转换注意和细节
4.5.3 强制类型转换
自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转换符 (),但可能造成 精度降低或溢出,格外要注意。
案例演示ForceConvert.java:
4.5.4 强制类型转换细节说明
4.5.5 基本数据类型转换-练习题
4.6 基本数据类型和String类型的转换
4.6.1 介绍和使用
4.6.2 注意事项
1)在将String类型转成基本数据类型时,,比如我们可以把"123",转成一 个整数,但是不能把"hello"转成一个整数
2)如果格式不正确,就会抛出异常,程序就会终止。
4.7 本章作业
第三章 运算符
3.1 运算符介绍
3.1.1 运算符介绍
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。
1) 算术运算符
2) 赋值运算符
3) 关系运算符 [比较运算符]
4) 逻辑运算符
5) 位运算符 [需要二进制基础]
6) 三元运算符
3.2 算术运算符
3.2.1 案例演示
///使用
System.out.println(10/4);//从数学来看是2.5,java中2System.out.println(10.0/4);//java是2.5//注释快捷键ctrl+/,再次输入ctrl+/取消注释
doubled=10/4;//java中10/4=2,2=>2.0System.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); //1System.out.println(-10 % 3); //-1System.out.println(10 %-3); //1System.out.println(-10 %-3);//-1//++的使用
//int i = 10;i++;//自增 等价于 i=i+1;=>i=11++i;//自增 等价于 i=i+1;=>i=12System.out.println("i=" + i);//12/*
作为表达式使用
前++:++i 先自增后赋值
后++:i++先赋值后自增
*/int j = 8;//int k = ++j; //等价 j=j+1;k=j;int k = j++; // 等价 k=j;j=j+1;System.out.println("k=" + k + "j=" + j);//8 9
3.2.2 细节说明
3.2.3 面试题
3.3 关系运算符(比较运算符)
1)关系运算符的结果都是boolean型,也就是要么是true,要么是false
2)关系表达式经常用在if结构的条件中或循环结构的条件中
案例演示:
inta=9; //提示:开发中,不可以使用a,bintb=8;System.out.println(a>b);//TSystem.out.println(a>=b); //TSystem.out.println(a<=b);//FSystem.out.println(a<b);//Fsystem.out.println(a == b); //FSystem.out.println(a != b); //Tboolean flag = a > b; //TSystem.out.println("flag=" + flag);
细节说明:
1) 关系运算符的结果都是boolean型,也就是要么是true,要么是false。
2) 关系运算符组成的表达式,我们称为关系表达式。 a>b
3) 比较运算符"=="不能误写成"="
3.4 逻辑运算符
3.4.1 介绍
用于连接多个条件(多个关系表达式),最终的结果也是一个boolean值。
1) 短路与 && , 短路或 |,取反 !
2) 逻辑与 &,逻辑或 |,^ 逻辑异或
说明逻辑运算规则:
1) a&b:&叫逻辑与:规则:当a和b同时为true,则结果为true,否则为false
2) a&&b:&&叫短路与:规则:当a和b同时为true,则结果为true,否则为false
3) a|b: |叫逻辑或,规则:当a和b,有一个为true,则结果为true,否则为false
4) a||b: ||叫短路或,规则:当a和b,有一个为true,则结果为true,否则为false
5) !a:叫取反,或者非运算。当a为true,则结果为false,当a为false是,结果为true
6) a^b:叫逻辑异或,当a和b不同时,则结果为true,否则为false
3.4.2 &&和&基本规则:
名称 语法 特点
短路与&& 条件1&&条件2 两个条件都为true,结果为true,否则false
逻辑与& 条件1&条件2 两个条件都为true,结果为true,否则false
3.4.3 &&和&案例演示
//&&短路与和&案例演示
intage=50;if(age>20&&age<90){System.out.println("ok100");}//&逻辑与使用
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
3.4.4 && 和 & 使用区别
1) &&短路与:如果第一个条件为false,则第二个条件不会判断,最终结果为false,效率高
2) & 逻辑与:不管第一个条件是否为false,第二个条件都要判断,效率低
3)开发中,我们使用的基本是使用短路与&&,效率高
3.4.5 ||和|基本规则
名称 语法 特点
短路或|| 条件1||条件2 两个条件中只要有一个成立,结果为true,否则为false
|逻辑或 条件1|条件2 只要有一个条件成立,结果为true,否则为false
3.4.6 ||和|案例演示
//||短路或和|逻辑或案例演示
//||规则:两个条件中只要有一个成立,结果为true,否则为false//|规则:两个条件中只要有一个成立,结果为true,否则为falseintage=50;if(age>20||age<30){System.out.println("ok100");}//&逻辑与使用
if(age>20|age<30){
System.out.println("ok200");}//看看区别
//(1)||短路或:如果第一个条件为true,
//则第二个条件不会判断,最终结果为true,效率高
//(2)|逻辑或:不管第一个条件是否为true,第二个条件都要判断,效率低
inta=4;intb=9;if(a>1||++b>4){//可以换成|测试
System.out.println("ok300");}System.out.println("a="+a+"b="+b);//410
3.4.7 ||和|使用区别
1) ||短路或:如果第一个条件为true,则第二个条件不会判断,最终结果为true,效率高
2) |逻辑或:不管第一个条件是否为true,第二个条件都要判断,效率低
3) 开发中,我们基本使用||
3.4.8 !取反基本规则
名称 语法 特点
!非(取反) !条件 如果条件本身成立,结果为false,否则为true
3.4.9 !案例演示
//!操作是取反T->F ,F->TSystem.out.println(60>20);//TSystem.out.println(!(60>20));//F//a^b:叫逻辑异或,当a和b不同时,则结果为true,否则为falsebooleanb=(10>1)^(3>5);System.out.println("b="+b);//T
3.4.10 ^案例演示
a^b:叫逻辑异或,当a和b不同时,则结果为true,否则为false
^逻辑异或,System.out.println((43));//?
3.4.11 练习题1请写出每题的输出结果
3.4.12 练习题2请写输出结果
3.5 赋值运算符
基本赋值运算符 = inta=10;
复合赋值运算符
+= ,-= ,*= , /= ,%= 等 , 重点讲解一个 += ,其它的使用是一个道理
a += b; [等价 a=a+b;]
a-= b; [等价 a=a-b;]
3.6 三元运算符
条件表达式 ? 表达式 1 : 表达式 2 ;
运算规则:
1.如果条件表达式为true,运算后的结果是表达式1;
2.如果条件表达式为false,运算后的结果是表达式2;
3.6.1 案例演示
inta=10;intb=99;//解读
//1.a>b为false//2.返回b--,先返回b的值,然后在b-1//3.返回的结果是99intresult=a>b?a++:b--;System.out.println("result="+result);System.out.println("a="+a);System.out.println("b="+b);
3.6.2 使用细节
1)表达式1和表达式2要为可以赋给接收变量的类型(或可以自动转换)
2)三元运算符可以转成if--else语句
3.7 运算符优先级
1) 运算符有不同的优先级,所谓优先级就是表达式运算中的运算顺序。
2) 只有单目运算符、赋值运算符是从右向左运算的。
3) 一览表, 不要背,使用多了,就熟悉了.
3.8 标识符的命名规则和规范
3.8.1 标识符命名规范[更加专业]
1) 包名:多单词组成时所有字母都小写:aaa.bbb.ccc//比如 com.hsp.crm
2) 类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz[大驼峰] 比如: TankShotGame
3) 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz [小 驼峰, 简称 驼峰法] 比如: tankShotGame
4) 常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ 比如 :定义一个所得税率 TAX_RATE
5) 后面我们学习到 类,包,接口,等时,我们的命名规范要这样遵守,更加详细的看文档.
3.9 关键字
关键字的定义和特点 (不用背)
定义:被Java语言赋予了特殊含义,用做专门用途的字符串(单词)
特点:关键字中所有字母都为小写
3.10 保留字
Java 保留字:现有Java版本尚未使用,但以后版本可能会作为关键字使用。自己命名标识符时要避免使用这些保留字byValue、cast、future、 generic、 inner、 operator、 outer、 rest、 var 、 goto 、const
3.11 键盘输入语句
在编程中,需要接收用户输入的数据,就可以使用键盘输入语句来获取。Input.java, 需要一个 扫描器(对象), 就是Scanner
3.12 进制(程序员的基本功)
3.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不区分大小写。
3.13 进制的图示
3.14 进制的转换(基本功)
二进制转换成十进制示例:
八进制转换成十进制示例:
十六进制转换成十进制示例:
规则:从最低位(右边)开始,将每个位上的数提取出来,乘以16的(位数-1)次方,然后求和。
案例:请将 0x23A 转成十进制的数
0x23A= 10 * 16^0 + 3 *16^1+2*16^2=10+48+512=57
十进制转换成二进制:
规则:将该数不断除以2,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制。 案例:请将 34 转成二进制 =0B00100010
十进制转换成八进制:
规则:将该数不断除以8,直到商为0为止,然后将每步得到的余数倒过来,就是对应的八进制。 案例:请将 131 转成八进制 =>0203
十进制转换成十六进制:
规则:将该数不断除以16,直到商为0为止,然后将每步得到的余数倒过来,就是对应的十六进制。
案例:请将 237 转成十六进制 =>0xED
3.15 二进制在运算中的说明
3.16 原码、反码、补码(重点 难点)
网上对原码,反码,补码的解释过于复杂,我这里精简几句话:(背下来)对于有符号的而言;
1.二进制的最高位是符号位:0表示正数,1表示负数
2.正数的原码,反码,补码都一样((三码合一)
3.负数的反码=它的原码符号位不变,其它位取反(0->1,1->0)
4.负数的补码=它的反码+1,负数的反码=负数的补码-15.0的反码,补码都是0
6. java没有无符号数,换言之,java中的数都是有符号的
7.在计算机运算的时候,都是以补码的方式来运算的
8.当我们看运算结果的时候,要看他的原码
3.17 位运算符
1) 算术右移 >>:低位溢出,符号位不变,并用符号位补溢出的高位
2) 算术左移 <<: 符号位不变,低位补0
3) >>> 逻辑右移也叫无符号右移,运算规则是: 低位溢出,高位补 0
4) 特别说明:没有 <<< 符号
第四章 程序控制结构
4..1 程序流程控制介绍
在程序中,程序运行的流程控制决定程序是如何执行的,是我们必须掌握的,主要有三大流程控制语句。
1) 顺序控制
2) 分支控制
3) 循环控制
2 顺序控制
4.2 顺序控制
4.3 分支控制if-else
让程序有选择的的执行,分支控制有三种
1) 单分支 if
2) 双分支 if-else
3) 多分支 if-elseif-....-else
单分支:
基本语法
if(条件表达式)
执行代码块;(可以有多条语句.)
}
说明:当条件表达式为ture时,就会执行{}的代码。如果为false,就不执行.特别说明,如果中只有一条语句,则可以不用在,建议写上0
案例说明
请大家看个案例
编写一个程序.可以输入人的年龄;如果该同志的年龄于18岁,则输出~您年龄大于18,要对自己的行为负责,送入监狱”
//编写一个程序,可以输入人的年龄,如果该同志的年龄大于18岁,//则输出"你年龄大于18,要对自己的行为负责,送入监狱"//思路分析
//1.接收输入的年龄,应该定义一个Scanner对象
//2.把年龄保存到一个变量intage//3.使用if判断,输出对应信息
//应该定义一个Scanner对象
Scanner myScanner = new Scanner(System.in);System.out.println("请输入年龄");//把年龄保存到一个变量 intageint age = myScanner.nextInt();//使用 if 判断,输出对应信息
if(age > 18) {System.out.println("你年龄大于 18,要对自己的行为负责,送入监狱");}System.out.println("程序继续...");
双分支:
//编写一个程序,可以输入人的年龄,如果该同志的年龄大于18岁,//则输出"你年龄大于18,要对
//自己的行为负责,送入监狱"。否则,输出"你的年龄不大这次放过你了."//思路分析
//1.接收输入的年龄,应该定义一个Scanner对象
//2.把年龄保存到一个变量intage//3.使用if-else判断,输出对应信息
//应该定义一个Scanner 对象
Scanner myScanner = new Scanner(System.in);System.out.println("请输入年龄");//把年龄保存到一个变量 intageint age = myScanner.nextInt();//使用 if-else 判断,输出对应信息
if(age > 18) {System.out.println("你年龄大于 18,要对自己的行为负责,送入监狱");} else {//双分支
System.out.println("你的年龄不大这次放过你了");}System.out.println("程序继续...");
多分支:
案例演示1:
输入自己的芝麻信用分:
如果:
1) 信用分为100分时,输出 信用极好;
2) 信用分为(80,99]时,输出 信用优秀;
3) 信用分为[60,80]时,输出 信用一般;
4) 其它情况 ,输出 信用 不及格
5) 请从键盘输入保国的芝麻信用分,并加以判断
代码:
//课堂练习
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,请重新输入:)");}
}
}
嵌套分支:
在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支的结构称为内层分支外面的分支结构称为外 层分支。建议: 不要超过3层 (可读性不好)
4.4 switch 分支结构
4.4.1 基本语法:
4.4.2 流程图
4.4.3 switch注意事项和细节讨论
4.4.4 switch 和 if 的比较
1)如果判断的具体数值不多,而且符合byte、short、int、char,enum[枚举],String这6种类型。虽然两个语句都可 以使用,建议使用swtich语句。
2)其他情况:对区间判断,对结果为boolean类型判断,使用if,if的使用范围更广
4.5 for循环控制 (!!!)
4.5.1 基本语法
说明:
1. for 关键字,表示循环控制
2. for 有四要素:(1)循环变量初始化(2)循环条件(3)循环操作(4)循环变量迭代
3. 循环操作 , 这里可以有多条语句,也就是我们要循环执行的代码
4. 如果 循环操作(语句) 只有一条语句,可以省略 {}, 建议不要省略
4.5.2 for 循环执行流程分析
注意事项和细节说明:
1) 循环条件是返回一个布尔值的表达式
2) for(;循环判断条件;) 中的初始化和变量迭代可以写到其它地方,但是两边的分号不能省略。
3) 循环初始值可以有多条初始化语句,但要求类型一样,并且中间用逗号隔开,循环变量迭代也可以有多条变量迭代语句,中间用逗号隔开。
4) 使用内存分析法,老师分析输出下面代码输出什么?
4.5.3 for循环练习题
publicclassForExercise{//编写一个main方法
publicstaticvoidmain(String[]args){
//打印1~100之间所有是9的倍数的整数,统计个数及总和.//思路分析
//打印1~100之间所有是9的倍数的整数,统计个数及总和
//化繁为简
//(1) 完成 输出 1-100的值
//(2) 在输出的过程中,进行过滤,只输出9的倍数 i%9==0//(3) 统计个数 定义一个变量 intcount=0; 当 条件满足时 count++;//(4) 总和 , 定义一个变量 intsum=0; 当条件满足时累积 sum+=i;//先死后活
//(1) 为了适应更好的需求,把范围的开始的值和结束的值,做出变量
//(2) 还可以更进一步 9 倍数也做成变量 intt=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);} }
4.6 while循环控制
4.6.1 基本语法
循环变量初始化;
while(循环条件){
循环体(语句);
循环变量迭代;
}
1) while循环也有四要素
2)只是四要素放的位置和for不一样
4.6.2 while循环执行流程分析
注意事项和细节说明:
1)循环条件是返回一个布尔值的表达式
2) while循环是先判断再执行语句
4.7 do..while循环控制
4.7.1 基本语法
循环变量初始化;
do{
循环体(语句);
循环变量迭代;
}while(循环条件);
4.7.2 说明:
1. do while 是关键字
2. 也有循环四要素, 只是位置不一样
3. 先执行,再判断,也就是说,一定会至少执行一次
4. 最后 有一个 分号 ;
4.7.3 画出流程图:
4.7.4 注意事项和细节说明
1)循环条件是返回一个布尔值的表达式
2) do..while循环是先执行,再判断,因此它至少执行一次
4.8 多重循环控制 (难点! 重点!)
4.8.1 介绍
1) 将一个循环放在另一个循环体内,就形成了嵌套循环。其中,for,while,do…while均可以作为外层循环和内层循环。 【建议一般使用两层,最多不要超过3层, 否则,代码的可读性很差】
2) 实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为false时,才会完全跳出内 层循环,才可结束外层的当次循环,开始下一次的循环。
3) 设外层循环次数为m次,内层为n次,则内层循环体实际上需要执行m*n次。
4.9 跳转控制语句-break
4.9.1 基本介绍:
break 语句用于终止某个语句块的执行,一般使用在switch或者循环[for,while,do-while]中
4.9.2 基本语法:
{ ……
break;
……
}
4.9.3 以 while 使用break 为例,画出示意图
4.9.4 快速入门:
4.10 跳转控制语句-continue
4.10.1 基本介绍:
1) continue语句用于结束本次循环,继续执行下一次循环。
2) continue语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环,这个和前面的标签的 使用的规则一样.
4.10.2 基本语法:
{ ……
continue;
……
}
4.10.3 以 while 使用continue 为例,画出示意图
4.10.4 快速入门案例
4.11 跳转控制语句-return
return使用在方法,表示跳出所在的方法,在讲解方法的时候,会详细的介绍,这里我们简单的提一下。注意:如果 return 写在 main方法,退出程序
第五章数组、排序和查找
5.1 数组介绍
数组可以存放多个同一类型的数据。数组也是一种数据类型,是引用类型。
即:数(数据)组(一组)就是一组数据
5.2 数组的使用
//演示数据类型数组名[]=new数据类型[大小]//循环输入5个成绩,//步骤
//1. 创建一个 double 数组,大小 5//(1) 第一种动态分配方式
//double scores[] = new double[5];//(2) 第 2 种动态分配方式, 先声明数组,再 new 分配空间
double scores[] ; //声明数组, 这时 scores 是 nullscores = new double[5]; // 分配内存空间,可以存放数据
//2. 循环输入
////scores.length 表示数组的大小/长度
Scanner myScanner = new Scanner(System.in);for( int i = 0; i < scores.length; i++) {System.out.println("请输入第"+ (i+1) +"个元素的值");scores[i] = myScanner.nextDouble();}//输出,遍历数组
System.out.println("==数组的元素/值的情况如下:===");for( int i = 0; i < scores.length; i++) {System.out.println("第"+ (i+1) +"个元素的值=" + scores[i]);保存到double数组,并输
5.2.1 使用方式2-动态初始化
1.先声明数组
语法:数据类型 数组名[]; 也可以 数据类型[] 数组名;
int a[]; 或者 int[] a;
2.创建数组
语法: 数组名=new 数据类型[大小];
a=new int[10];
5.2.2 使用方式3-静态初始化
5.3 数组使用注意事项和细节
1) 数组是多个相同类型数据的组合,实现对这些数据的统一管理
2) 数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用。
3) 数组创建后,如果没有赋值,有默认值 int 0,short 0, byte 0, long 0, float 0.0,double 0.0,char \u0000,boolean false,String null
4) 使用数组的步骤 1. 声明数组并开辟空间 2 给数组各个元素赋值 3 使用数组
5) 数组的下标是从0开始的。
6) 数组下标必须在指定范围内使用,否则报:下标越界异常,比如int [] arr=new int[5]; 则有效下标为 0-4
7) 数组属引用类型,数组型数据是对象(object)
代码:
//1. 数组是多个相同类型数据的组合,实现对这些数据的统一管理
//int[] arr1 = {1, 2, 3, 60,"hello"};//String->intdouble[] arr2 = {1.1, 2.2, 3.3, 60.6, 100};//int->double//2. 数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用
String[] arr3 = {"北京","jack","milan"};//3. 数组创建后,如果没有赋值,有默认值
//int0,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[]arr=newint[5];则有效下标为0-4//即数组的下标/索引最小0最大数组长度-1(4)int[]arr=newint[5];//System.out.println(arr[5]);//数组越界
5.4 数组赋值机制
1) 基本数据类型赋值,这个值就是具体的数据,而且相互不影响。
int n1 = 2; int n2 = n1;
2) 数组在默认情况下是引用传递,赋的值是地址。
看一个案例,并分析数组赋值的内存图(重点, 难点.)。
int[] arr1 = {1,2,3};
int[] arr2 = arr1;
5.5 数组拷贝
将 int[] arr1 = {10,20,30}; 拷贝到 arr2 数组, 要求数据空间是独立的:
//将 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;//输出arr1System.out.println("====arr1 的元素====");for(int i = 0; i < arr1.length; i++) {System.out.println(arr1[i]);//10,20,30}
System.out.println("====arr2的元素====");for(inti=0;i<arr2.length;i++){System.out.println(arr2[i]);//}
5.7 数组反转
要求:把数组的元素内容反转。
arr {11,22,33,44,55,66} {66,55,44,33,22,11}
方式1:通过找规律反转【思路分析】
//定义数组
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:使用逆序赋值方式
//定义数组
int[] arr = {11, 22, 33, 44, 55, 66};//使用逆序赋值方式
//思路
//1. 先创建一个新的数组 arr2,大小 arr.length//2. 逆序遍历 arr,将 每个元素拷贝到 arr2的元素中(顺序拷贝)//3. 建议增加一个循环变量 j->0->5int[] arr2 = new int[arr.length];//逆序遍历 arrfor(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");
5.8 数组添加/扩容
要求:实现动态的给数组添加元素效果,实现对数组扩容。
1)原始数组使用静态分配int[]arr={1,2,3}
2)增加的元素4,直接放在数组的最后arr={1,2,3,4}
3)用户可以通过如下方法来决定是否继续添加,添加成功,是否继续?y/n
代码:
/*
要求:实现动态的给数组添加元素效果,实现对数组扩容。ArrayAdd.java1.原始数组使用静态分配 int[]arr={1,2,3}2.增加的元素4,直接放在数组的最后 arr={1,2,3,4}3.用户可以通过如下方法来决定是否继续添加,添加成功,是否继续?y/n
思路分析
1. 定义初始数组 int[]arr={1,2,3}//下标 0-22. 定义一个新的数组 int[]arrNew=newint[arr.length+1];3. 遍历 arr 数组,依次将arr的元素拷贝到 arrNew数组
4. 将 4 赋给 arrNew[arrNew.length- 1] = 4;把 4 赋给arrNew 最后一个元素
5. 让 arr 指向 arrNew; arr=arrNew; 那么 原来arr数组就被销毁
6. 创建一个 Scanner可以接受用户输入
*///初始化数组
7. 因为用户什么时候退出,不确定,老师使用 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("你退出了添加...");
5.9 排序的介绍
排序是将多个数据,依指定的顺序进行排列的过程。
排序的分类:
5.9.1 内部排序:
指将需要处理的所有数据都加载到内部存储器中进行排序。包括(交换式排序法、选择 式排序法和插入式排序法);
5.9.2 外部排序法:
数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。包括(合并排序法和直接合并排序法)。
5.10 冒泡排序法
冒泡排序(BubbleSorting)的基本思想是:通过对待排序序列从后向前(从下标较大的元素开始),依次比较相邻元素 的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。
案例:
下面我们举一个具体的案例来说明冒泡法。我们将五个无序:24,69,80,57,13使用冒泡排序法将其排成一个从小到大的有序数列。
思路->走代码, 你可以自己完整的分析冒泡的执行流程,并可以不看老师代码,也可以写出代码.
/*数组 [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-1for( int i = 0; i < arr.length- 1; i++) {//外层循环是 4 次
for( int j = 0; j < arr.length- 1- i; j++) {//4 次比较-3 次-2 次-1 次
//如果前面的数>后面的数,就交换
if(arr[j] > arr[j + 1]) {temp = arr[j];arr[j] = arr[j+1];}}arr[j+1] = temp;System.out.println("\n==第"+(i+1)+"轮==");for(int j = 0; j < arr.length; j++) {System.out.print(arr[j] + "\t");
}}
// for( int j = 0; j < 4; j++) {//4 次比较// }//如果前面的数>后面的数,就交换
if(arr[j] > arr[j + 1]) {temp = arr[j];arr[j] = arr[j+1];arr[j+1] = 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[j+1];arr[j+1] = 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[j+1];arr[j+1] = 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[j+1];arr[j+1] = temp;}// System.out.println("\n==第 4 轮==");// for(int j = 0; j < arr.length; j++) {// }}System.out.print(arr[j] + "\t");
5.11 查找
介绍:
在java中,我们常用的查找有两种:
1)顺序查找
2)二分查找
案例:
/*
有一个数列:白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王猜数游戏:
从键盘中任意输入一个名称,判断数列中是否包含此名称【顺序查找】
要求:如果找到了,就提示找到,并给出下标值
思路分析
1.定义一个字符串数组
2.接收用户输入,遍历数组,逐一比较,如果有,则提示信息,并退出
*/
//定义一个字符串数组
String[] names = {"白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王"};Scanner myScanner = new Scanner(System.in);System.out.println("请输入名字");String findName = myScanner.next();//遍历数组,逐一比较,如果有,则提示信息,并退出
//这里老师给大家一个编程思想/技巧, 一个经典的方法
int index =-1;for(int i = 0; i < names.length; i++) {//比较 字符串比较 equals, 如果要找到名字就是当前元素
if(findName.equals(names[i])) {System.out.println("恭喜你找到 " + findName);System.out.println("下标为= " + i);//把 i 保存到 indexindex = i;break;//退出
}}if(index ==-1) { //没有找到
System.out.println("sorry ,没有找到 " + findName);}
5.12 多维数组-二维数组
5.12.1 快速入门案例
请用二维数组输出如下图形:
0 0 0 0 0 0
0 0 1 0 0 0
0 2 0 3 0 0
0 0 0 0 0 0
/*
请用二维数组输出如下图形
0 0 00000 0 10000 2 03000 0 0000*///什么是二维数组:
//解读
//1. 从定义形式上看 int[][]int[][] arr = { {0, 0, 0, 0, 0, 0},//2. 可以这样理解,原来的一维数组的每个元素是一维数组, 就构成二维数组
{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)如果我们要访问第(i+1)个一维数组的第j+1个值arr[i][j];//举例访问3,=》他是第3个一维数组的第4个值arr[2][3]System.out.println("第3个一维数组的第4个值="+arr[2][3]);//3//输出二维图形
for(inti=0;i<arr.length;i++){//遍历二维数组的每个元素
//遍历二维数组的每个元素(数组)//解读
//1.arr[i]表示二维数组的第i+1个元素比如arr[0]:二维数组的第一个元素
//2.arr[i].length得到对应的每个一维数组的长度
for(intj=0;j<arr[i].length;j++){System.out.print(arr[i][j]+"");//输出了一维数组
}System.out.println();//换行
}}}
5.12.2 使用方式1:动态初始化
1)语法:类型[][]数组名=new类型[大小][大小]
2)比如:inta[][]=newint[2][3]
3)使用演示
4)二维数组在内存的存在形式(!!画图)
//intarr[][]=newint[2][3];intarr[][];//声明二维数组
arr=newint[2][3];//再开空间
arr[1][1]=8;//遍历arr数组
for(inti=0;i<arr.length;i++){for(intj=0;j<arr[i].length;j++){//对每个一维数组遍历
System.out.print(arr[i][j]+"");}System.out.println();//换行
5.12.3 使用方式2: 动态初始化
先声明:类型 数组名[][];
再定义(开辟空间) 数组名 =new 类型[大小][大小]
赋值(有默认值,比如int 类型的就是0)
5.12.4 使用方式3: 动态初始化-列数不确定
/*
看一个需求:动态创建下面二维数组,并输出
i = 0: 1i = 1: 2 2i = 2: 3 3 3
一个有三个一维数组, 每个一维数组的元素是不一样的
*///创建 二维数组,一个有3个一维数组,但是每个一维数组还没有开数据空间
int[][] arr = new int[3][];for(int i = 0; i < arr.length; i++) {//遍历 arr 每个一维数组
//给每个一维数组开空间 newarr[i] = new int[i + 1];//如果没有给一维数组 new,那么 arr[i]就是null//遍历一维数组,并给一维数组的每个元素赋值
for(int j = 0; j < arr[i].length; j++) {arr[i][j] = i + 1;//赋值
}System.out.println("=====arr元素=====");//遍历arr输出
for(inti=0;i<arr.length;i++){//输出arr的每个一维数组
for(intj=0;j<arr[i].length;j++){System.out.print(arr[i][j]+"");}System.out.println();//换行
5.12.5 使用方式4:静态初始化
定义类型数组名[][] ={{值1,值2..},{值1,值2..},{值1,值2..}}
使用即可[固定方式访问]
比如: int[][]arr={{1,1,1},{8,8,9},{100}};
解读
1.定义了一个二维数组arr
2.arr有三个元素(每个元素都是一维数组)
3.第一个一维数组有3个元素,第二个一维数组有3个元素,第三个一维数组有1个元素
5.13 二维数组使用细节和注意事项
1)一维数组的声明方式有: int[]x或者intx[]
2)二维数组的声明方式有: int[][]y或者int[]y[]或者int y[][]
3)二维数组实际上是由多个一维数组组成的,它的各个一维数组的长度可以相同,也可以不相同。比如:map[][]是 一个二维数组 intmap[][]={{1,2},{3,4,5}}
由map[0]是一个含有两个元素的一维数组,map[1]是一个含有三个元素的一维数组构成,我们也称为列数不等 的二维数组
5.14 二维数组练习
第六章面向对象编程(基础部分)
6.1 类与对象
一个程序就是一个世界,有很多事物(对象[属性, 行为])
类与对象的关系示意图:
面向对象的方式解决养猫问题:
6.1.1 类和对象的区别和联系
1) 类是抽象的,概念的,代表一类事物,比如人类,猫类.., 即它是数据类型.
2) 对象是具体的,实际的,代表一个具体事物, 即 是实例.
3) 类是对象的模板,对象是类的一个个体,对应一个实例
对象在内存中存在形式(重要的)必须搞清楚:
6.1.2 属性/成员变量/字段
基本介绍:
1) 从概念或叫法上看: 成员变量 = 属性 =field(字段) (即 成员变量是用来表示属性的,授课中,统一叫 属性)
//编写一个main方法
publicstaticvoidmain(String[]args){}}classCar{Stringname;//属性,成员变量,字段fielddoubleprice;Stringcolor;String[]master;//属性可以是基本数据类型,也可以是引用类型(对象,数组)}
2)属性是类的一个组成部分,一般是基本数据类型,也可是引用类型(对象,数组)。比如我们前面定义猫类的intage就 是属性
注意事项和细节说明:
1)属性的定义语法同变量,示例:访问修饰符属性类型属性名;
这里简单的介绍访问修饰符:控制属性的访问范
有四种访问修饰符public,proctected,默认,private,后面我会详细介绍
2)属性的定义类型可以为任意类型,包含基本类型或引用类型
3)属性如果不赋值,有默认值,规则和数组一致。具体说:int 0,short0,byte0,long0,float0.0,double0.0,char\u0000, booleanfalse,Stringnull
案例:
publicclassPropertiesDetail{
//编写一个main方法
public static void main(String[] args) {//创建Person 对象
//p1 是对象名(对象引用)//new Person() 创建的对象空间(数据) 才是真正的对象
Person p1 = new Person();//对象的属性默认值,遵守数组规则://int0,short 0, byte 0, long 0, float 0.0,double 0.0,char \u0000,boolean false,String nullSystem.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;}
6.1.3 如何创建对象
1) 先声明再创建
Cat cat ; //声明对象 cat
cat = new Cat(); //创建
2) 直接创建
Cat cat = new Cat();
6.1.4 如何访问属性
基本语法
对象名.属性名;
案例演示赋值和输出
cat.name ;
cat.age;
cat.color;
类和对象的内存分配机制(重要):
我们定义一个人类(Person)(包括 名字,年龄)。
6.1.5 类和对象的内存分配机制
Java内存的结构分析:
1)栈:一般存放基本数据类型(局部变量)
2)堆:存放对象(Catcat,数组等)
3)方法区:常量池(常量,比如字符串),类加载信息
Java创建对象的流程简单分析:
Personp=newPerson();
p.name=“jack”;
p.age=10
1)先加载Person类信息(属性和方法信息,只会加载一次)
2)在堆中分配空间,进行默认初始化(看规则)
3)把地址赋给p,p就指向对象
4) 进行指定初始化, 比如 p.name=”jack” p.age=10
6.2 成员方法
6.2.1 基本介绍
在某些情况下,我们要需要定义成员方法(简称方法)。比如人类:除了有一些属性外(年龄,姓名..),我们人类还有一 些行为比如:可以说话、跑步..,通过学习,还可以做算术题。这时就要用成员方法才能完成。现在要求对Person类完善。
6.2.2 成员方法快速入门
1)添加speak成员方法,输出“我是一个好人”
2)添加cal01成员方法,可以计算从1+..+1000的结果
3)添加cal02成员方法,该方法可以接收一个数n,计算从1+..+n的结果
4)添加getSum成员方法,可以计算两个数的和
publicclassMethod01{//编写一个main方法
publicstaticvoidmain(String[]args){//方法使用
//1.方法写好后,如果不去调用(使用),不会输出
//2.先创建对象,然后调用方法即可
Personp1=newPerson();p1.speak();//调用方法
p1.cal01();//调用cal01方法
p1.cal02(5);//调用cal02方法,同时给n=5p1.cal02(10);//调用cal02方法,同时给n=10//调用getSum方法,同时num1=10,num2=20
//把 方法 getSum 返回的值,赋给 变量 returnResint 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. {} 方法体,可以写我们要执行的代码
public void speak() {System.out.println("我是一个好人");}//5. 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;}}
6.2.3 方法的调用机制原理:(重要!-示意图!!!)
6.2.4 成员方法的好处
1)提高代码的复用性
2)可以将实现的细节封装起来,然后供其他用户来调用即可
6.2.5 成员方法的定义
访问修饰符返回数据类型方法名(形参列表..){//方法体语句;
return返回值; }
1)形参列表:表示成员方法输入cal(intn),getSum(intnum1,intnum2)
2)返回数据类型:表示成员方法输出,void表示没有返回值
3)方法主体:表示为了实现某一功能代码块
4) return语句不是必须的。
6.2.6 注意事项和使用细节
AAa=newAA();int[]res=a.getSumAndSub(1,4);System.out.println("和="+res[0]);System.out.println("差="+res[1]);//细节:调用带参数的方法时,一定对应着参数列表传入相同类型或兼容类型的参数
byteb1=1;byteb2=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]resArr[1] = n1- n2;return resArr;}//2. 返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)////
具体看 getSumAndSub//3. 如果方法要求有返回数据类型,则方法体中最后的执行语句必须为 return 值;//
而且要求返回值类型必须和return的值类型一致或兼容
public double f1() {double d1 = 1.1 * 3;int n = 100;return n; // int->double//return d1; //ok? double-> int}//,最好是见名知意
public void f2() {//如果方法是void,则方法体中可以没有return语句,或者 只写 return;//提示:在实际工作中,我们的方法都是为了完成某个功能,所以方法名要有一定含义
System.out.println("hello1");System.out.println("hello1");System.out.println("hello1");int n = 10; = n1 + n2;
//return ;}}
访问修饰符 (作用是控制 方法使用的范围)
如果不写默认访问,[有四种:public,protected, 默认,private], 具体在后面说
返回数据类型
1) 一个方法最多有一个返回值 [思考,如何返回多个结果 返回数组 ]
2) 返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)
3) 如果方法要求有返回数据类型,则方法体中最后的执行语句必须为 return 值; 而且要求返回值类型必须和return的 值类型一致或兼容
4) 如果方法是void,则方法体中可以没有return语句,或者 只写 return
方法名
遵循驼峰命名法,最好见名知义,表达出该功能的意思即可, 比如 得到两个数的和 getSum, 开发中按照规范
6.2.7 类定义的完善
6.3 成员方法传参机制(非常非常重要)
6.3.1 基本数据类型的传参机制
publicclassMethodParameter01{//编写一个main方法
publicstaticvoidmain(String[]args){inta=10;intb=20;//创建AA对象名字objAAobj=newAA();obj.swap(a,b);//调用swapSystem.out.println("main方法a="+a+"b="+b);//a=10b=20}}
class AA{public void swap(int a,int b){System.out.println("\na 和 b 交换前的值\na=" + a + "\tb=" + b);//a=10 b=20//完成了 a 和 b的交换
int tmp = a;a =b;b =tmp;System.out.println("\na 和 b 交换后的值\na=" + a + "\tb=" + b);//a=20 b=10}}
6.3.2 引用数据类型的传参机制
1) 看一个案例
B类中编写一个方法test100,可以接收一个数组,在方法中修改该数组,看看原来的数组是否变化?会变化
B类中编写一个方法test200,可以接收一个Person(age,sal)对象,在方法中修改该对象属性,看看原来的对象是否变化?会变化.
public class MethodParameter02 {//编写一个main方法
public static void main(String[] args) {//测试
Bb=newB();// int[] arr = {1, 2, 3};// b.test100(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(p);//测试题, 如果 test200 执行的是 p=null,下面的结果是 10//测试题, 如果 test200 执行的是 p=newPerson();..., 下面输出的是10System.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 类中编写一个方法test100,
//可以接收一个数组,在方法中修改该数组,看看原来的数组是否变化
public void test100(int[] arr) {arr[0] = 200;//修改元素
//遍历数组
System.out.println(" test100 的 arr 数组 ");for(int i = 0; i < arr.length; i++) {System.out.print(arr[i] + "\t");}System.out.println();}}
2) 结论及示意图
引用类型传递的是地址(传递也是值,但是值是地址),可以通过形参影响实参!
6.4 方法递归调用(非常非常重要,比较难)
6.4.1 基本介绍
简单的说: 递归就是方法自己调用自己,每次调用时传入不同的变量.递归有助于编程者解决复杂问题,同时可以让代码变 得简洁
6.4.2 递归能解决什么问题?
6.4.3 递归举例
1) 打印问题
2) 阶乘问题
public class Recursion01 {//编写一个main方法
public static void main(String[] args) {Tt1 = newT();t1.test(4);//输出什么? n=2 n=3 n=4int 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;}}}
6.4.4递归重要规则
6.5 方法重载(OverLoad)
6.5.1基本介绍
java 中允许同一个类中,多个同名方法的存在,但要求 形参列表不一致!
6.5.2 重载的好处
1) 减轻了起名的麻烦
2) 减轻了记名的麻烦
6.5.3 快速入门案例
1) calculate(int n1, int n2) //两个整数的和
2) calculate(int n1, double n2) //一个整数,一个 double 的和
3) calculate(double n2, int n1)//一个 double ,一个 Int 和
4) calculate(int n1, int n2,int n3)//三个 int 的和
6.5.4 注意事项和使用细节
6.5.5 课堂练习题
6.6 可变参数
6.6.1 基本概念
java允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。 就可以通过可变参数实现
6.6.2 基本语法
访问修饰符返回类型方法名(数据类型...形参名){ }6.6.3快速入门案例
6.6.3 快速入门案例
看一个案例类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)); //106System.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;return n1 + n2 + n3 + n4;// public int sum(int n1, int n2, int n3, int n4) {//4 个数的和
// }//.....//上面的三个方法名称相同,功能相同, 参数个数不同-> 使用可变参数优化
//解读
//1.int...表示接受的是可变参数,类型是int,即可以接收多个int(0-多)//2.使用可变参数时,可以当做数组来使用即nums可以当做数组
//3.遍历nums求和即可
publicintsum(int...nums){//System.out.println("接收的参数个数="+nums.length);intres=0;for(inti=0;i<nums.length;i++){res+=nums[i];}return res;} }
6.6.4 注意事项和使用细节
6.7 作用域
6.7.1 基本使用
6.7.2 注意事项和细节使用
public class VarScopeDetail {
//编写一个main方法
public static void main(String[] args) {Person p1 = new Person();/*
属性生命周期较长,伴随着对象的创建而创建,伴随着对象的销毁而销毁。
局部变量,生命周期较短,伴随着它的代码块的执行而创建,
伴随着代码块的结束而销毁。即在一次方法调用过程中
*///p1.say();//当执行 say 方法时,say 方法的局部变量比如name,会创建,当say执行完毕后
//name 局部变量就销毁,但是属性(全局变量)仍然可以使用
//Tt1 = newT();t1.test(); //第 1 种跨类访问对象属性的方式
t1.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 {//细节: 属性可以加修饰符(publicprotected 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";//可以
}}
6.8 构造方法/构造器
6.8.1 看一个需求
我们来看一个需求:前面我们在创建人类的对象时,是先把一个对象创建好后,再给他的年龄和姓名属性赋值,如 果现在我要求,在创建人类的对象时,就直接指定这个对象的年龄和姓名,该怎么做? 这时就可以使用构造器。
6.8.2 基本语法
[修饰符] 方法名(形参列表)
{ 方法体; }
说明:
1) 构造器的修饰符可以默认, 也可以是publicprotectedprivate
2) 构造器没有返回值
3) 方法名 和类名字必须一样
4) 参数列表 和 成员方法一样的规则
5) 构造器的调用, 由系统完成
6.8.3 基本介绍
构造方法又叫构造器(constructor),是类的一种特殊的方法,它的主要作用是完成对新对象的初始化。它有几个特点:
1) 方法名和类名相同
2) 没有返回值
3) 在创建对象时,系统会自动的调用该类的构造器完成对象的初始化。
6.8.4 快速入门
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);//smithSystem.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;}}
6.8.5 注意事项和使用细节
publicclassConstructorDetail{//编写一个main方法
publicstaticvoidmain(String[]args){Personp1=newPerson("king",40);//第1个构造器
Personp2=newPerson("tom");//第2个构造器
Dogdog1=newDog();//使用的是默认的无参构造器
}}class Dog {//如果程序员没有定义构造器,系统会自动给类生成一个默认无参构造器(也叫默认构造器)//使用javap 指令 反编译看看
/**/
默认构造器
Dog() {}//一旦定义了自己的构造器,默认的构造器就覆盖了,就不能再使用默认的无参构造器,
//除非显式的定义一下,即: Dog(){} 写 (这点很重要)//public Dog(String dName) {//...}Dog() { //显式的定义一下 无参构造器
}}class Person {String name;int age;//默认 0//第 1 个构造器
publicPerson(StringpName,intpAge){name=pName;age=pAge;}//第2个构造器,只指定人名,不需要指定年龄
publicPerson(StringpName){name=pName;}}
6.9 对象创建的流程分析
6.9.1 看一个案例
学习完构造器后,我们类的定义就应该更加完善了
6.10 this 关键字
6.10.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关键字来解决
publicDog(Stringname,int age){//构造器
//this.name就是当前对象的属性namethis.name=name;//this.age就是当前对象的属性agethis.age=age;System.out.println("this.hashCode="+this.hashCode());}publicvoidinfo(){//成员方法,输出属性x信息
System.out.println("this.hashCode="+this.hashCode());System.out.println(name+"\t"+age+"\t");}}
6.10.2 深入理解this
为了进一步理解this,我们再看一个案例
6.10.3 this 的注意事项和使用细节
1) this 关键字可以用来访问本类的属性、方法、构造器
2) this 用于区分当前类的属性和局部变量
3) 访问成员方法的语法:this.方法名(参数列表);
4)访问构造器语法:this(参数列表);注意只能在构造器中使用(即只能在构造器中访问另外一个构造器,必须放在第一 条语句)
5) this不能在类定义的外部使用,只能在类定义的方法中使用。
第 七 章 面向对象编程(中级部分)
7.1 工具介绍
IDE(集成开发环境):
1) IDEA 全称 IntelliJ IDEA
2) 在业界被公认为最好的Java开发工具
3) IDEA是JetBrains 公司的产品,总部位于捷克的首都布拉格
4) 除了支持Java开发,还支持HTML,CSS,PHP,MySQL,Python等
Eclipse:
1) Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。
2) 最初是由IBM 公司耗资3000万美金开发的下一代IDE开发环境
3) 2001 年11月贡献给开源社区
4) Eclipse 是目前最优秀的Java开发IDE之一
7.2 包
7.2.1 看一个应用场景
现在有两个程序员共同开发一个java项目,程序员xiaoming希望定义一个类取名Dog,程序员xiaoqiang也想定义一个类也叫 Dog。两个程序员为此还吵了起来.怎么办?-》包
7.2.2 包的三大作用
1.区分相同名字的类
2.当类很多时,可以很好的管理类[看Java API文档]
3.控制访问范围
7.2.3 包基本语法
package com.nspeau;
说明:
1. package关键字,表示打包.
2.com.hspedu:表示包名
7.2.4 包的本质分析(原理)
7.2.5 快速入门
7.2.6 包的命名
7.2.7 常用的包
一个包下,包含很多的类,java中常用的包有:
1) java.lang.* //lang 包是基本包,默认引入,不需要再引入
2) java.util.* //util 包,系统提供的工具包, 工具类,使用 Scanner
3) java.net.* //网络包,网络开发
4) java.awt.* //是做 java 的界面开发,GUI
7.2.8 如何引入包
com.nspedu.pkg : lmportO1.java
语法:import 包;
我们引入一个包的主要目的是要使用该包下的类
比如import java.util.Scanner; 就只是引入一个类Scanner。
import java.util.*; // 表示将java.util包所有都引入
7.2.9 注意事项和使用细节
1. package的作用是声明当前类所在的包,需要放在类的最上面,一个类中最多只有
一句package
2. import指令位置放在package的下面,在类定义前面,可以有多句且没有顺序要求。
7.3 访问修饰符
7.3.1 基本介绍
java 提供四种访问控制修饰符号,用于控制方法和属性(成员变量)的访问权限(范围)
1) 公开级别:用public 修饰,对外公开
2) 受保护级别:用protected修饰,对子类和同一个包中的类公开
3) 默认级别:没有修饰符号,向同一个包的类公开.
4) 私有级别:用private修饰,只有类本身可以访问,不对外公开
7.3.2 使用的注意事项
1)修饰符可以用来修饰类中的属性,成员方法以及类
2)只有默认的和public才能修饰类!,并且遵循上述访问权限的特点。
3)因为没有学习继承,因此关于在子类中的访问权限,我们讲完子类后,在回头讲解
4)成员方法的访问规则和属性完全一样.
7.4 面向对象编程三大特征
面向对象编程有三大特征:封装、继承和多态
7.5 封装
7.5.1 封装介绍
封装(encapsulation)就是把抽象出的数据[属性]和对数据的操作[方法]封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作[方法],才能对数据进行操作。
7.5.2 封装的理解和好处
1)隐藏实现细节:方法(连接数据库)<--调用(传入参数..)
2)可以对数据进行验证,保证安全合理
7.5.3 封装的实现步骤 (三步)
1)将属性进行私有化private【不能直接修改属性】
2)提供一个公共的(public)set方法,用于对属性判断并赋值
public void setXxx(类型参数名) { //Xxx表示某个属性
//加入数据验证的业务逻辑
属性=参数名;
}
3)提供一个公共的(public)get方法,用于获取属性的值
public数据类型getXxx({ //权限判断,Xxx某个属性
return xx;
}
7.5.4 快速入门案例
那么在java中如何实现这种类似的控制呢?
请大家看一个小程序。
不能随便查看人的年龄,工资等隐私,并对设置的年龄进行合理的验证。年龄合理就设置,否则给默认年龄,必须在1-120,年龄,工资不能直接查看,
name的长度在2-6字符之间
packagecom.hspedu.encap;publicclassEncapsulation01{publicstaticvoidmain(String[]args){//如果要使用快捷键alt+r,需要先配置主类
//第一次,我们使用鼠标点击形式运算程序,后面就可以用
Personperson=newPerson();person.setName("知昂可");person.setAge(30);person.setSalary(30000);System.out.println(person.info());System.out.println(person.getSalary());//如果我们自己使用构造器指定属性
Personsmith=newPerson("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) {}//构造器 alt+insertpublic 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 {this.name = "无名人";}}public int getAge() {return age;}System.out.println("名字的长度不对,需要(2-6)个字符,默认名字");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;} }
7.6 面向对象编程-继承
7.6.1 为什么需要继承
一个小问题,提出代码复用的问题。
我们编写了两个类,一个是Pupil类(小学生),一个是Graduate(大学毕业生)
问题:两个类的属性和方法有很多是相同的,怎么办?
=>继承(代码复用性~)
7.6.2 继承基本介绍和示意图
继承可以解决代码复用,让我们的编程更加靠近人类思维.当多个类存在相同的属性(变量)和方法时,可以从这些类中 抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends来声明继承父类即可。画出继承的示意图
7.6.3 继承的基本语法
7.6.4 快速入门案例
packagecom.hspedu.extend_.improve_;importcom.hspedu.extend_.Graduate;importcom.hspedu.extend_.Pupil;publicclassExtends01{publicstaticvoidmain(String[]args){com.hspedu.extend_.Pupilpupil=newPupil();pupil.name="银角大王~";pupil.age=11;pupil.testing();pupil.setScore(50);pupil.showInfo();System.out.println("=======");com.hspedu.extend_.Graduategraduate=newGraduate();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 类
publicclassPupilextendsStudent{publicvoidtesting(){System.out.println("小学生"+name+"正在考小学数学..");}}packagecom.hspedu.extend_.improve_;publicclassGraduateextendsStudent{publicvoidtesting(){//和Pupil不一样
System.out.println("大学生"+name+"正在考大学数学..");}}
7.6.5 继承给编程带来的便利
1)代码的复用性提高了
2)代码的扩展性和维护性提高了
7.6.6 继承的深入讨论/细节问题
1)子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问,但是私有属性和方法不能在子类直接访 问,要通过父类提供公共的方法去访问
2)子类必须调用父类的构造器,完成父类的初始化
3)当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无 参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过
4)如果希望指定去调用父类的某个构造器,则显式的调用一下:super(参数列表)
5) super在使用时,必须放在构造器第一行(super只能在构造器中使用)
6) super()和this()都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
7) java所有类都是Object类的子类,Object是所有类的基类.
8)父类构造器的调用不限于直接父类!将一直往上追溯直到Object类(顶级父类)
9)子类最多只能继承一个父类(指直接继承),即java中是单继承机制。
10)不能滥用继承,子类和父类之间必须满足is-a的逻辑关系
案例:
我们看一个案例来分析当子类继承父类,创建子类对象时,内存中到底发生了什么?
提示:当子类对象创建好后,建立查找的关系
package com.hspedu.extend_;/*** 讲解继承的本质
*/public class ExtendsTheory {public static void main(String[] args) {Son son = new Son();//内存的布局
//?-> 这时请大家注意,要按照查找关系来返回信息
//(1) 首先看子类是否有该属性
//(2) 如果子类有这个属性,并且可以访问,则返回信息
//(4) 如果父类没有就按照(3)的规则,继续找上级父类,直到Object...System.out.println(son.name);//返回就是大头儿子
//System.out.println(son.age);//返回的就是 39}}class GrandPa { //爷类
//(3) 如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息..)//System.out.println(son.getAge());//返回的就是 39System.out.println(son.hobby);//返回的就是旅游
String name = "大头爷爷";
Stringhobby="旅游";}classFatherextendsGrandPa{//父类
Stringname="大头爸爸";privateintage=39;publicintgetAge(){returnage;}}classSonextendsFather{//子类
Stringname="大头儿子";}
子类创建的内存布局:
7.7 super关键字
7.7.1 介绍:
super代表父类的引用,用于访问父类的属性、方法、构造器
基本语法:
1.访问父类的属性,但不能访问父类的private属性
super.属性名;
2.访问父类的方法,不能访问父类的private方法
super.方法名(参数列表);
3.访问父类的构造器:
super(参数列表); 只能放在构造器的第一句,只能出现一句!
7.7.2 super 给编程带来的便利/细节
1.调用父类的构造器的好处(分工明确,父类属性由父类初始化,子类的属性由子
类初始化)
2.当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须
通过super。如果没有重名,使用super、this、直接访问是一样的效果!
3. super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用
super去访问爷爷类的成员;如果多个基类(上级类)中都有同名的成员,使用super访问遵循就近原则。A->B->C,当然也需要遵守访问权限的相关规则
7.7.3 super 和 this 的比较
7.8 方法重写/覆盖(override)
7.8.1 基本介绍
简单的说:方法覆盖(重写)就是子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的方法
代码案例:
packagecom.hspedu.override_;publicclassAnimal{publicvoidcry(){System.out.println("动物叫唤..");}publicObjectm1(){returnnull;}publicStringm2(){returnnull;}publicAAAm3(){returnnull;}protectedvoideat(){}}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,//
子类方法返回类型是Stringpublic String m1() {return null;}public Object m2() {//这里Object 不是 String的子类,因此编译错误return null;}public BBB m3() {
// returnnull;// }//细节:子类方法不能缩小父类方法的访问权限【演示】
//public>protected>默认>privatepublicvoideat(){}}classAAA{}classBBBextendsAAA {}packagecom.hspedu.override_;publicclassOverride01{publicstaticvoidmain(String[]args){//演示方法重写的情况
Dogdog=newDog();dog.cry();//ctrl+b}}
7.8.2 注意事项和使用细节
方法重写也叫方法覆盖,需要满足下面的条件
1. 子类的方法的形参列表,方法名称,要和父类方法的形参列表,方法名称完全一样。
2. 子类方法的返回类型和父类方法返回类型一样,或者是父类返回类型的子类
比如父类返回类型是Object ,子类方法返回类型是String
public object getInfo(){
public String getInfo(){
3.子类方法不能缩小父类方法的访问权限 public > protected >默认>private
void sayok() {
public oid sayok(){
7.9 面向对象编程-多态
7.9.1 多[多种]态[状态]基本介绍
方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的。
7.9.2 多态的具体体现
1)方法的多态
重写和重载就体现多态
案例说明:
packagecom.hspedu.poly_;publicclassPloyMethod{publicstaticvoidmain(String[]args){
//方法重载体现多态
Aa=newA();//这里我们传入不同的参数,就会调用不同sum方法,就体现多态
System.out.println(a.sum(10,20));System.out.println(a.sum(10,20,30));//方法重写体现多态
Bb=newB();a.say();b.say();
}}classB{//父类
publicvoidsay(){System.out.println("Bsay()方法被调用...");}}classAextendsB{//子类
publicintsum(intn1,intn2){//和下面sum构成重载
returnn1+n2;}publicintsum(intn1,intn2,intn3){returnn1+n2+n3;}publicvoidsay(){System.out.println("Asay()方法被调用...");}}
注意:
(1)一个对象的编译类型和运行类型可以不一致
(2)编译类型在定义对象时,就确定了,不能改变
(3)运行类型是可以变化的.
(4)编译类型看定义时 = 号的左边, 运行类型看 = 号的右边
案例:
Animal animal = new Dog0; 【animal编译类型是Animal,运行类型Dog】
animal = new Cat(); 【animal的运行类型变成了Cat,编译类型仍然是 Animal)
代码:
packagecom.hspedu.poly_.objectpoly_;publicclassAnimal{publicvoid cry(){System.out.println("Animalcry()动物在叫....");}}packagecom.hspedu.poly_.objectpoly_;publicclassCatextendsAnimal{publicvoidcry(){System.out.println("Catcry()小猫喵喵叫...");}}packagecom.hspedu.poly_.objectpoly_;publicclassDogextendsAnimal{
publicvoidcry(){System.out.println("Dogcry()小狗汪汪叫...");}}packagecom.hspedu.poly_.objectpoly_;publicclassPolyObject{publicstaticvoidmain(String[]args){//体验对象多态特点
//animal编译类型就是Animal,运行类型DogAnimalanimal=newDog();//因为运行时,执行到改行时,animal运行类型是Dog,所以cry就是Dog的cryanimal.cry();//小狗汪汪叫
//animal编译类型Animal,运行类型就是Catanimal=newCat();animal.cry();//小猫喵喵叫
}}
7.9.3 多态注意事项和细节讨论
多态的前提是:两个对象(类)存在继承关系
多态的向上转型:
1)本质:父类的引用指向了子类的对象
2)语法:父类类型 引用名=new子类类型);
3)特点:编译类型看左边,运行类型看右边。
可以调用父类中的所有成员(需遵守访问权限),不能调用子类中特有成员;
最终运行效果看子类的具体实现!
多态向下转型:
1)语法:子类类型 引用名=(子类类型)父类引用;
2)只能强转父类的引用, 不能强转父类的对象
3)要求父类的引用必须指向的是当前目标类型的对象
4)当向下转型后,可以调用子类类型中所有的成员
7.9.4 java 的动态绑定机制(非常非常重要.)
Java 重要特性: 动态绑定机制
代码:
packagecom.hspedu.poly_.dynamic_;publicclassDynamicBinding{publicstaticvoidmain(String[]args){//a的编译类型A,运行类型BAa=newB();//向上转型
System.out.println(a.sum());//?40->30System.out.println(a.sum1());//?30->20}}classA{//父类
publicinti=10;//动态绑定机制:publicintsum(){//父类sum()returngetI()+10;//20+10
}public int sum1() {//父类 sum1()return i + 10;//10 + 10}public int getI() {//父类 getIreturn 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;}
7.9.5 多态的应用
1)多态数组
数组的定义类型为父类类型,里面保存的实际元素类型为子类类型
应用实例:现有一个继承结构如下:要求创建1个Person对象、2个Student对象和2个Teacher对象,统一放在数组 中,并调用每个对象 say方法
应用实例升级:如何调用子类特有的方法,比如 Teacher有一个teach,Student有一个study 怎么调用?
代码:
packagecom.hspedu.poly_.polyarr_;publicclassPerson{//父类
privateStringname;privateintage;publicPerson(Stringname,intage){this.name=name;this.age=age;}publicStringgetName(){
returnname;}publicvoidsetName(Stringname){this.name=name;}publicintgetAge(){returnage;}publicvoidsetAge(intage){this.age=age;}publicStringsay(){//返回名字和年龄
returnname+"\t"+age;}}packagecom.hspedu.poly_.polyarr_;publicclassStudentextendsPerson{privatedoublescore;publicStudent(Stringname,intage,doublescore){
super(name, age);this.score = score;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}//重写父类say@Overridepublic String say() {return "学生 " + super.say() + " score=" + score;}//特有的方法
public void study() {}}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方法
@Overridepublic 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);//循环遍历多态数组,调用sayfor (int i = 0; i < persons.length; i++) {System.out.println(persons[i].say());//动态绑定机制
//老师提示:person[i] 编译类型是 Person,运行类型是是根据实际情况有JVM来判断
//这里大家聪明. 使用 类型判断 + 向下转型.if(persons[i] instanceof Student) {//判断 person[i] 的运行类型是不是 StudentStudent 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("你的类型有误, 请自己检查...");} }} }
2) 多态参数
方法定义的形参类型为父类类型,实参类型允许为子类类型
定义员工类Employee,包含姓名和月工资[private],以及计算年工资getAnnual的方法。普通员工和经理继承了员工,经理类多了奖金bonus属性和管理manage方法,普通员工类多了work方法,普通员工和经理类要求分别重弓getAnnual方法
测试类中添加一个方法showEmpAnnual(Employee e),实现获取任何员工对象的年工资,并在main方法中调用该方法[e.getAnnual0]
测试类中添加一个方法,testWork,如果是普通员工,则调用work方法,如果是经理,则调用manage方法
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
publicdoublegetAnnual(){returnsuper.getAnnual()+bonus;}}packagecom.hspedu.poly_.polyparameter_;publicclassWorkerextendsEmployee{publicWorker(Stringname,doublesalary){super(name,salary);}publicvoidwork(){System.out.println("普通员工"+getName()+"isworking");}@OverridepublicdoublegetAnnual(){//因为普通员工没有其它收入,则直接调用父类方法
returnsuper.getAnnual();}}packagecom.hspedu.poly_.polyparameter_;publicclassPloyParameter{publicstaticvoidmain(String[]args){Workertom=newWorker("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());//动态绑定机制.}public void testWork(Employee e) {if(e instanceof Worker) {((Worker) e).work();//有向下转型操作
} else if(e instanceof Manager) {} else {//添加一个方法,testWork,如果是普通员工,则调用work方法,如果是经理,则调用manage方法
((Manager) e).manage();//有向下转型操作
System.out.println("不做处理...");}}}
7.10 Object类详解
7.10.1 equals方法
==和equals的对比[面试题]
7.10.2 如何重写equals方法
应用实例: 判断两个Person对象的内容是否相等,如果两个Person对象的各个属性值都一样,则返回true,反之false。
package com.hspedu.object_;public class EqualsExercise01 {public static void main(String[] args) {Person person1 = new Person("jack", 10, '男');Person person2 = new Person("jack", 20, '男');System.out.println(person1.equals(person2));//假
}}//判断两个Person对象的内容是否相等,
//如果两个Person对象的各个属性值都一样,则返回true,反之falseclass Person{ //extends Objectprivate String name;private int age;private char gender;//重写Object 的 equals 方法
public boolean equals(Object obj) {if(this == obj) {//判断如果比较的两个对象是同一个对象,则直接返回truereturn 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 ,则直接返回falsereturn 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;
}publicvoidsetAge(intage){this.age=age;}publicchargetGender(){returngender;}publicvoidsetGender(chargender){this.gender=gender;}}
7.10.3 hashCode 方法
1) 提高具有哈希结构的容器的效率!
2) 两个引用,如果指向的是同一个对象,则哈希值肯定是一样的!
3) 两个引用,如果指向的是不同对象,则哈希值是不一样的
4) 哈希值主要根据地址号来的!, 不能完全将哈希值等价于地址。
7.10.4 toString方法
1)基本介绍
默认返回:全类名+@+哈希值的十六进制,【查看Object的toString方法】
子类往往重写toString方法,用于返回对象的属性信息
2)重写toString方法,打印对象或拼接对象时,都会自动调用该对象的toString形式.
3) 当直接输出一个对象时,toString 方法会被默认的调用, 比如 System.out.println(monster); 就会默认调用 monster.toString()
7.10.5 finalize方法
1)当对象被回收时,系统自动调用该对象的finalize方法。子类可以重写该方法,做一些释放资源的操作
2)什么时候被回收:当某个对象没有任何引用时,则jvm就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来 销毁该对象,在销毁该对象前,会先调用finalize方法。
3)垃圾回收机制的调用,是由系统来决定(即有自己的GC算法),也可以通过System.gc()主动触发垃圾回收机制,测 试:Car[name]
提示:我们在实际开发中,几乎不会运用finalize,所以更多就是为了应付面试.
7.11 断点调试(debug)
7.11.1 一个实际需求
1.在开发中,新手程序员在查找错误时,这时老程序员就会温馨提示,可以用断点调试,—步一步的看源码执行的过程,从而发现错误所在。
2重要提示:在断点调试过程中,是运行状态,是以对象的运行类型来执行的.
A extends B; Bb = new AO; b.xx0;
7.11.2 断点调试介绍
1.断点调试是指在程序的某一行设置一个断点,调试时,程序运行到这一行就会停住,
然后你可以一步一步往下调试,调试过程中可以看各个变量当前的值,出错的话,调试到出错的代码行即显示错误,停下。进行分析从而找到这个Bug
2.断点调试是程序员必须掌握的技能。
3.断点调试也能帮助我们查看java底层源代码的执行过程,提高程序员的Java水平。
7.11.3 断点调试的快捷键
F7(跳入) F8(跳过) shift+F8(跳出)F9(resume,执行到下一个断点)
F7:跳入方法内
F8: 逐行执行代码.
shift+F8: 跳出方法
因为内容太多,分开写了。
之后的部分在这里 ——> Java零基础入门2