第一章:Java语言概述
1、软件开发介绍
- 软件类型:系统软件、应用软件
- Windows-DOS命令:
- 创建目录:md 目录名
- 进入目录:cd 目录名
- 输出文件:echo 内容 > 文件名.doc
- 删除文件:del 文件名.doc
- 删除目录:rd 目录名
- Windows-DOS命令:
2、计算机编程语言介绍
- 计算机语言的进程:机器语言 --> 汇编语言 --> 高级语言(面向过程、面向对象)
3、Java语言概述
- Java简史
- Java是Web应用程序的首选语言
- Java技术体系:JavaSE、JavaEE、JavaME
- Java是类C语言、纯粹的面向对象语言
4、运行机制及运行过程
- 特点:面向对象、健壮性、跨平台性
- JVM是Java实现跨平台的核心
- Java 自动垃圾回收
5、Java的环境搭建
- JDK、JRE、JVM的关系
- JDK的安装下载
- 环境变量配置:
- JAVA_HOME:Java的安装目录
- path:%JAVA_HOME%\bin
6、开发体验-HelloWorld
- 编译:javac HelloWorld.java
- 执行:java HelloWorld
7、常见问题及解决方法
8、注释
- 对程序进行解释说明,增强可读性、可以调试代码
1. 单行注释://
2. 多行注释:/* */
3. 文档注释:/** */ 文档注释可以使用javadoc进行解析,生成一套以网页文件形式体现的说明文档
9、Java API 文档
- JDK1.6的中文文档翻译写的比较准确
10、良好的编程风格
- 正确的注释和注释风格(整个类或者整个方法使用文档注释,某行代码使用单行或多行注释)
- 正确的缩进和空白(使用Tab进行缩进)
- 块的风格
11、常用的Java开发工具
Eclipse
IDEA
第二章:基本语法
1、关键字和保留字
关键字
- 定义:被Java赋予了特殊含义,有专门用途的单词
- 特点:关键字中所有的字母都是小写
保留字
- 定义:java中尚未使用 ,但是后续版本可能会使用
- 保留字有:goto const Friendly …
2、标识符
标识符
- 定义:对各种变量、方法、类进行命名时使用的字符,凡是自己可以起名的地方都叫标识符
命名规则:
- 由26个大小写字母、0到9的数字、_ $ 组成
- 不能以数字开头
- 不能是关键字、保留字
- 严格区分大小写,长度无限制
- 标识符不能包含空格
命名规范:
- 包名:多单词组成是全部小写
- 类名、接口名:多单词组成时,所有单词的首字母大写
- 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始首字母大写
- 常量名:所有单词字母大写并用下划线连接
- 注意: 命名要见名知意,提高阅读性
3、变量
概念:
- 内存中的一个存储区域,该区域的数据可以中同一类型范围类不断变化
- 程序中最基本的存储单元,包括变量类型、变量名和存储的值
作用:
- 用于在内存中保存值
定义变量的格式:
- 数据类型 变量名 = 变量值;
注意点:
- 变量必须先声明再使用
- 变量是有使用范围的,超出了它的范围就不能使用了
- 同一个作用域中,不能存在同名的变量
变量的分类
- 基本数据类型:
- 整数类型:byte(-128~127)、short、int、long
- 浮点类型:float、double
- 字符型:char
- 布尔型:boolean
- 引用数据类型:
- 类:class
- 接口:interface
- 数组:array
基本数据类型之间的运算规则
- 自动类型转换:
- 结论:当容量小的数据类型和容量大的数据类型做运算时,结果自动提升为容量大的数据类型
- byte、char、short 彼此间运算时结果都是int
- byte、char、 short —> int —> long —> float —> double
- 强制类型转换:
- 结论:将大容量的数据类型转换为小容量的数据类型,使用时加上强制转换符( ),但是可能会导致精度丢失或者溢出。
- 例如:int a = (int)b;
String类型变量的使用
- String属于引用数据类型
- 声明String类型变量时,使用一对 “ ”
- String可以和8种基本数据类型进行运算,运算符为【+】==>运算出来的结果还是String
- String转换成数值类型时,需要使用包装类
关于进制
- 二进制:0B或者0b开头
- 十进制:12、99
- 八进制:0开头
- 十六进制:0x开头
4、运算符
算术运算符:
- 加(+)、减(-)、乘( * )、除(/)、取余(%)
- (前)++X:先自增 1,后运算 (后)X++:先运算,后自增 1 注意点:自增1不会改变本身变量的数据类型
- (前)–X:先自减 1,后运算 (后)X–:先运算,后自减 1
赋值运算符:
- 赋值(=)、(+=)、(-=)、(*=)、(/=)、(%=) 注意点:不会改变本身变量的数据类型
- 可以连续赋值 :i1 = i2 = 10;
比较运算符:
- 等于(==)、不等于(!=)、大于(>)、小于(<)、大于等于(>=)、小于等于(<=)、instanceof
- 比较运算符的结果是boolean类型的
- 区分 == 和 = 的区别
逻辑运算符:
- 逻辑与(&)、逻辑或(|)、逻辑非(!)、短路与(&&)、短路或(||)、逻辑异或(^)
- 逻辑运算符操作的都是Boolean类型的变量
- & 和&& 区别:运算结果是相同的,当左边为true时二者都会执行右边的运算,&&如果左边为false时,不执行右边的运算
- | 和 || 的区别:运算结果是相同的,当左边为false时二者都会执行右边的运算,|| 如果左边为true时,不执行右边的运算
位运算符:
- 左移(<<)、右移(>>)、无符号右移(>>>)、与(&)、或(|)、异或(^)、取反(~)
- 位运算符操作的都是整型变量
- 在一定范围内,每左移1位时相当于 * 2 (当超过其范围时,这个数将变成负数)
- 在一定范围内,每右移1位时相当于 / 2
三元运算符:
- 结构:(条件表达式)? 表达式1 : 表达式2;
- 表达式的结果是boolean类型,条件表达式的真假决定执行表达式1或者表达式2
- 表达式1 和 表达式2 应该是同一数据类型
运算符的优先级:
- 下表中具有最高优先级的运算符在的表的最上面,最低优先级的在表的底部。
5、程序流程控制
基本流程结构有三种:
顺序结构
分支结构
循环结构
分支结构:
if - else有三种结构:
说明:
- if - else结构是可以互相嵌套的
- 如果if - else结构中执行语句只有一句时,对应的一对{ }可以省略
第一种:
if(条件表达式) {
执行表达式
}
第二种:
if(条件表达式) {
执行表达式1
}else {
执行表达式2
}
第三种:
if(条件表达式) {
执行表达式1
}else if(条件表达式){
执行表达式2
}else if(条件表达式){
执行表达式3
}else {
执行表达式4
}
switch - case结构
说明:
- 根据switch表达式中的值,依次匹配各个case中的常量。一旦匹配成功,则进入响应的case结构中条用其执行语句
- break关键字可以使用在switch-case中,一旦执行到break直接跳出该结构
- switch表达式只能是如下类型:byte、short、int、枚举类型、String类型
- case语句中只能声明常量,不能声明范围
- default位置可以灵活配置
switch(表达式) {
case 常量1:
执行语句1;
// break;(可选)
case 常量2:
执行语句2;
break;
case 常量3:
执行语句3;
break;
. . . . . .
default:
执行语句;
}
循环结构:
分类:
-
for循环
-
while循环
-
do - while循环
for循环结构:
说明:
//循环结构的四要素:1.初始值、2.循环条件、3.循环体、4.迭代条件
for(int i = 0; i < X; i++) {
循环体;
}
while循环结构:
说明:
//要注意千万别漏了迭代条件,否则就变成了死循环
while(循环条件){
循环体;
迭代条件;
}
do - while循环结构:
说明:
//do - while结构至少会执行一次循环体
//技巧:不在循环条件部分限制次数的结构:for(;;)或while(true)
//结束循环的方式:循环条件中返回false或者使用break
do {
循环体;
迭代条件;
} while(循环条件);
嵌套循环
说明:
- 将一个循环结构A声明在另外一个循环结构B的循环体中
- 外层循环:控制行数
- 内层循环:控制列数
- 内层循环结构体遍历了一次,只相当于外层循环体执行了一次
break、continue关键字的使用
使用范围:(默认就近原则,也可以结束指定标识的循环)
break | switch - case、循环结构中 | 结束当前循环 | 键字的后面不能声明执行语句 |
---|---|---|---|
continue | 循环结构中 | 结束当次循环 | 关键字的后面不能声明执行语句 |
第三章:数组
1、数组的概述
- 概述:数组是多个相同数据类型数据按一定顺序排列的集合,并使用一个名字命名,通过编号的方式对这些数据进行统一管理
- 常见概念:数组名、下标(索引)、元素、数组的长度
- 特点:
- 数组是有序的
- 数组属于引用数据类型的变量,数组的元素可以是基本数据类型,也可以是引用数据类型
- 数组是连续的内存空间
- 数组的长度一旦确定,就不能修改
- 分类:
- 按照维数:一维数组、二维数据、多维数组
- 按照数据的元素类型:基本数据类型数组、引用数据类型数组
2、一维数据
- 数组的声明和初始化:
- 数据类型[ ] 数组名 = new 数据类型[长度] :int[ ] array = new int[10];
- 静态初始化:int[ ] ids = new int[ ] {1001,1002,1003};
- 动态初始化:int[ ] ids = new int[3];
- 数组一旦初始化完成,长度就确定了,不再改变
- 数组的调用:
- 数组元素的调用是通过下标 , array[0]
- 数组的下标从0开始,到数据长度 -1 结束
- 数组的长度:
- 通过数组属性:length :array.length
- 数据元素的遍历:
- 方法:for(int i = 0;i < array.length; i++)
- 数组元素的默认初始化值:
- 数组元素是整型:0
- 数组元素是浮点型:0.0
- 数组元素是字符型:0 或者 ’\u0000‘ , 而非 ’0‘
- 数组元素是布尔型:false
- 数组元素是引用数据类型:null
- 数组的内存解析:
- 栈内存:存放局域变量
- 堆内存:存放new 出来的结构
3、多维数据
-
数组的声明和初始化:
-
数据类型[ ] [ ] 数组名 = new 数据类型 [长度] [长度]
- 静态初始化:int [ ] [ ] ids = new int[ ] {{1,2,3},{4,5},{6,7,8}};
- 动态初始化:int [ ] [ ] ids = new int [3] [3]; 或者 int[ ] [ ] ids = new int[3] [ ];
-
数组的调用:
- 数组元素的调用是通过下标 , array[0] [0]
- 数组的下标从0开始,到数据长度 -1 结束
-
数组的长度:
-
通过数组属性:length
-
数据元素的遍历:两个for循环输出
-
for(int i = 0;i < array.length; i++) for(int j = 0;i < array[ i ].length; j++)
-
数组元素的默认初始化值:
- 针对初始化方式一:int[ ] [ ] arr = new int[4] [3];
- 外层元素的初始值为:地址值
- 内存元素为:与一维数组初始化情况相同
- 针对初始化方式二:int[ ] [ ] arr = new int[4] [ ];
- 外层元素的初始值为:null
- 内存元素为:不能调用,报空指针异常
- 针对初始化方式一:int[ ] [ ] arr = new int[4] [3];
-
数组的内存解析:
栈内存:存放局域变量
堆内存:存放new 出来的结构
-
4、数组中涉及到的常用算法
- 数组元素的赋值(杨辉三角、回形数)
- 求数组元素的最大值、最小值、平均值、总和
- 数组的复制、反转、查找(线性查找、二分法查找)
- 数组的元素的排序
5、Arrays工具类的使用
常见的方法:
- 判断两个数组是否相等:boolean equlas(int[ ]a , int[ ] b)
- 输出数组信息:String toString(int[ ] a)
- 将指定值填充到数组:void fill(int[ ] a,,int val)
- 数组排序:void sort(int[ ] a)
- 数组排序后二分法检索:int binarySearch(int[ ] a, int key)
6、数组中的常见异常
- 数组角标越界异常:ArrayIndexOutOfBoundExcetion
- 空指针异常:NullPointerExcetion
第四章:面向对象(上)
三大主线:
- Java类及类的成员:属性、方法、构造器
- 面向对象的三大特性:封装性、继承性、多态性
- 其他关键字:this、super、static、final、abstract、interface、package、import
1、面向过程和面向对象
区别:
- 面对过程:强调的是功能行为,以函数为最小单位
- 面向对象:强调具备了功能的对象,以类/对象为最小单位
2、Java基本元素:类和对象
- 类:类是对一类事物的描述,是抽象的、概念上的定义
- 对象:对象是实际存在的该类事物的每个个体,也称为实例(instance)
- 概述:面向对象程序设计的重点在于类的设计,其实就是类的成员的设计
类的成员:
- 属性:对应类中的成员变量
- 方法:对应类中的成员方法
- 类和对象的使用(面向对象的思想实现落地的步骤):
- 创建类,设计类的成员
- 创建类的对象
- 通过“对象.属性”或“对象.方法”调用对象的结构
3、对象的创建和使用
class Person {
String name;
int age;
public void eat(){
//方法体
}
}
- 对象的创建:Person person = new Person();
- 对象属性调用:person.name
- 对象方法调用:person.eat()
类的多个对象间的关系:
- 每个对象都独立的拥有一套类的属性,修改其中一个对象属性不影响其他对象的属性
对象的内存解析:
- 方法区:类的加载信息、常量池、静态域
- 虚拟机栈:存在局部变量
- 堆:存放对象的属性(存放我们new出来的数组、对象)
- 引用类型的变量,只能存储两类值:null 或者 地址值
匿名对象的使用:
- 创建的对象,没有显式的赋给一个变量名
- 匿名对象只能调用一次
匿名对象用法例子:
PhoneMall mall = new PhoneMall();
mall.show(new Phone( )); //匿名对象使用
class PhoneMall {
public void show(Phone phone) {
phone.sendEmail( );
phone.playGame( );
}
}
4、类的成员之一:属性
- 属性:成员变量、局部变量对比
- 相同点:
- 定义变量的格式:数据类型 变量名 = 变量值;
- 先声明,后使用
- 变量都有其对应的作用域
- 不同点:
- 在类中声明的位置的不同
- 属性:直接定义在类的{ }中。
- 局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
- 关于权限修饰符的不同
- 常见的权限修饰符:public、private、protected、缺省
- 属性:在声明的时候指明其权限,可以使用权限修饰符
- 局部变量:不能使用权限修饰符
- 默认初始化情况
- 属性:根据其类型,都有默认初始化值(
- 整型:0, 浮点型:0.0 ,字符型:0 或‘u0000’ ,布尔型:false,引用数据类型:null)
- 局部变量:没有默认初始化值,使用时必须先赋值(注意点:形参必须在调用时赋值)
- 属性:根据其类型,都有默认初始化值(
- 在内存中加载的位置
- 属性:加载到堆空间
- 局部变量:加载到栈空间
- 总结属性赋值的先后顺序:1 - 2 - 3 - 4
- 默认初始化
- 显式初始化
- 构造器赋值
- 通过“对象.方法” 或“对象.属性”的方式赋值
- 在类中声明的位置的不同
5、类的成员之二:方法
- 方法定义:描述类应该具有的功能
- 分类:
- 无返回值无参数 void methon();
- 有返回值无参数 int method();
- 无返回值有参数 void method(String name);
- 有返回值有参数 String method(String name);
- 方法的声明:
权限修饰符 返回值类型 方法名(形参列表) {
方法体
}
- 说明:
- 关于权限修饰符:默认方法的权限修饰符public
- 返回值类型:有返回值、无返回值
- 如果方法有返回值,则必须在方法声明时,指定返回值得类型。同时,方法中,需要使用return关键字来返回指定类型的变量或常量
- 如果方法没有返回值,则方法声明时使用void表示。如果一定要写返回则写return;
- 方法名:属于标识符,应该遵循标识符的命名规则、规范,“见名知意”。
- 形参列表:方法可以声明0到N个形参
- 方法体:方法功能的具体实现
- 注意:
- 方法的使用中,可以调用当前类的属性或者方法
- 方法中不能定义再方法
- return关键字:
- 适用范围:使用在方法体中
- 作用:1、结束方法 2、针对于有返回值类型的方法,使用“return 数据” 方法返回需要的数据
6、方法进阶
方法的重载:
- 概念:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或参数类型不同即可
- 特点:
- ”两同一不同“:同一个类、相同方法名,参数列表不同(参数类型、个数不同 )
- 判断是否重载:跟方法的权限修饰符、返回值类型、形参变量名、方法体都没关系
- 如何确定某一个方法:方法名------>参数列表
可变形参的方法:
- 概念:允许直接定义能和多个实参相匹配的形参
- 用法:
- 可变个数形参的格式:参数类型 … 参数名
- 当调用可变个数形参的方法时,可以传入0到N个参数
- 可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载
- 可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载
- 可变个数形参在方法的形参中,必须声明在末尾
- 可变个数形参在方法的形参中,最多只能声明一个可变形参
方法参数的值传递机制:
- 基本数据类型:传的是值
- 引用数据类型:传的是地址值
- 形参:方法定义时,声明在( )中的参数
- 实参:方法调用时,实际传给形参的数据
值传递机制:
- 如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值
- 如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值
递归方法:
- 定义:一个方法体内调用它自身
- 理解递归:
- 方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无序循环控制
- 递归一定要向已知方法递归
7、OPP特征之一:封装和隐藏
封装性的定义:
- 隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性,可维护性
封装性的体现:
- 将类的属性使用private关键字进行私有化,同时提供公共的(public)方法来获取(getXXX)和设置(setXXX)属性的值
- 不对外暴露的私有方法
- 单例模式(将构造器私有化)
- 如果不希望类在包外被调用,可以将类设置为缺省的
- 封装性需要权限修饰符来配合:
- 权限从小到大:private、缺省(default)、protected、public
- 这4中权限修饰符可以用来修饰类及类的内部结构:属性、方法、构造器、内部类
8、类的成员之三:构造器
构造器作用:
- 创建对象
- 给对象进行初始化
构造器的说明:
- 如果没有显式的定义类的构造器,系统将默认提供一个空参的构造器
- 定义构造器的格式:权限修饰符 类名(形参列表){ }
- 一个类中定义多个构造器,构成方法的重载
- 一旦我们显式的定义了类的构造器后,系统不再提供默认的空参构造器
- 一个类中,至少会有一个构造器
拓展知识:JavaBean介绍:
- 概述:JavaBean是一种Java语言写成的可重用组件
- 符合如下标准:
- 类是公共的
- 有一个无参的公共的构造器
- 有属性,且有对应的get、set方法
9、关键字:this
this关键字的使用:
- this可以用来(修饰)调用:属性、方法、构造器
- this修饰属性和方法时,可以理解为:当前对象 或 当前正在创建的对象
- this调用构造器
- 在类的构造器中,可以显示的使用“this(形参列表)”方式,调用本类中指定的其他构造器
- 在构造器中不能通过“this(形参列表)”方式调自己
- 在一个类中有N个构造器,那最多存在N - 1 构造器中使用了“this(形参列表)”
- “this(形参列表)” 必须声明在当前构造器的首行
- 构造器内部,最多只能声明一个“this(形参列表)”方式调用其他构造器
10、关键字:package、import
package关键字使用:
- 为了更好的实现项目中类的管理,提供包的概念
- 使用package来声明类或接口所属的包,声明在源文件的首行
- 包,属于标识符,遵循标识符的命名规则、规范、“见名知意”
- 每 “ . ”一次代表一层文件目录
- 同一个包下,不能声明同名的类或接口,不同包下可以命名同名类或接口
MVC设计模式:
- 定义:MVC是常用的设计模式之一,将整个程序分为三个层次:视图模型层、控制器层、数据模型层
- 视图模型层:主要处理数据(model.bean/domain)
- 控制器层:处理业务逻辑
- 数据模型层:显示数据
import关键字使用:
- 在源文件中显式的使用import结构导入指定包下的类、接口
- 位置:声明在包的声明与类的声明之间
- 如果需要导入多个结构,则并列写出即可
- 可以使用“xxx.”的方式,表示可以导入xxx包下的所有结构
- 如果使用的类或接口是在lang包下的,则可以省略import结构
- 如果使用的类或接口是在本包下的,则可以省略import结构
- 如果源文件中,使用了不同包下的同名的类,则必须至少有一个类需要以全类名的方式显示
- 使用“xxx.*” 方式表明可以调用xxx 包下的所有结构
- import . static:导入指定类或接口中的静态结构:属性或方法
面向对象(中)
1、OPP特征二:继承性
- 定义:
- 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
- 好处:
- 继承的出现减少了代码冗余,提高了代码的复用性
- 继承的出现,更有利于功能的扩展
- 继承的出现让类与类之间产生了关系,提供了多态的前提
- 格式:
- class A extends B { }
- A:子类、派生类
- B:父类、超类、基类
- 体现:
- 一旦子类A继承了父类B以后,子类A中就获取了父类B中声明的结构:属性、方法
- 特点的,父类中声明为private的属性或者方法,子类继承父类后,子类仍然能获取父类中的私有的结构
- 子类继承父类后,子类还可以声明自己特有的属性或方法,实现功能拓展
- 规定:
- 一个类可以被多个子类继承
- Java中类的继承性,只能是单继承,即一个类只能有一个父类
- 子父类的关系是相对的概念
- 子类直接继承的父类叫做直接父类,间接继承的父类叫做间接父类
- 子类继承父类之后,就获取了直接父类以及间接父类中声明的属性和方法
- Object类:
- 如果我们没有显式的声明一个类的父类的话,则此类默认继承于java.lang.object类
- Object是所有类的父类(超类)
- 所有类都具有Object类的功能
2、方法的重写(override)
- 定义:
- 在子类中可以根据需要对从父类中继承来的方法进行改造,也称为方法的重写、覆盖。在程序执行时,子类的方法将覆盖父类的方法。
- 应用:
- 方法重写后,当创建子类的对象后调用父子类中同名同参的方法时,实际执行的是子类重写父类后的方法。
- 规定:
- 子类重写的方法必须和父类被重写的方法具有相同的方法名称、参数列表
- 子类重写的方法的返回值类型不能大于父类被重写的方法的返回值类型
- 父类被重写的方法返回值类型是void,子类重写的方法的返回值只能是void
- 父类被重写的方法返回值类型是A,则子类重写的方法的返回值类型可以是A或A的子类
- 父类被重写的方法返回值类型是基本数据类型,则子类重写的方法的返回值类型必须也是相同基本数据类型
- 子类重写的方法使用的访问权限不能小于父类被重写的方法的访问权限
- 子类不能重写父类中声明为private权限的方法
- 子类重写的方法抛出的异常类型不能大于父类被重写的方法抛出的异常类型
- 注意:
- 子类和父类中同名同参的方法必须同时声明为非static(重写),或者同时声明为static(非重写)。因为static方法是属于类方法
3、四种访问权限修饰符
- 权限说明:
- pirvate:在同一个类中可用其修饰属性、方法
- 缺省( default):在同一个包中可用其修饰的属性、方法
- protected:在不同包的子类可用其修饰的属性、方法
- public:在同一工程中可用其修饰的属性、方法
4、super关键字
- 使用方式:
- super理解为:父类的
- super可以用来调用父类的属性、方法、构造器
- super调用属性、方法:
- 在子类的方法或构造器中,通过使用“super.属性”或者“super.方法”的方式,显式的调用父类的属性或方法,但是通常我们习惯省略”super.“
- 当子类和父类存在同名的属性时,我们想要在子类中调用父类的中声明的属性,必须使用“super.属性”的方式,表明调用的是父类中的属性。
- 当子类和父类存在同名的方法时,我们想要在子类中调用父类的中被重写的方法,必须使用“super.方法”的方式,表明调用的是父类中的方法。
- super调用构造器:
- 我们可以在子类的构造器中显示的使用“super(形参列表)”的方式,调用父类指定的构造器。
- “super(形参列表)”的使用,必须声明在子类构造器的首行。
- 我们在类的构造器中,针对于“this(形参列表)”或“super(形参列表)”只能二选一,不能同时出现。
- 在构造器首行,没有显式的声明“this(形参列表)”或“super(形参列表)”,则默认调用父类的空参构造器。
- 在类的多个构造器中,至少有一个构造器中使用了“super(形参列表)”,调用父类的构造器。
5、子类对象实例化过程
子类对象实例化的全过程:
- 从结果上来看:(继承性)
- 子类继承父类以后,就获取了父类中声明的属性或方法。
- 创建子类的对象,在堆空间中,就会加载所有父类中声明的属性。
- 从过程上来看:
- 当我们通过子类的构造器创建子类的对象时,我们一定会直接或者间接的调用其父类的构造器,进而调用父类的上级父类构造器,一直到到Object类的空参构造器。
- 明确:虽然创建子类对象时,调用了父类的构造器,但自始至终只有一个对象,即为new的子类对象。
6、OOP特征三:多态性
-
理解多态性:
- 一种事物的多种形态
- 对象的多态性:父类的引用指向子类的对象(子类的对象赋值给父类的引用
Person p = new Man();
-
多态的使用:
- 当调用子父类同名同参的方法时,实际执行的是子类重写父类的方法(虚拟方法调用)
- 有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法
- 对象的多态性只适用于方法,不适用与属性
- 多态性是运行时的行为
-
总结:编译看左边,运行看右边
- 使用前提:类的继承关系
-
方法的重写
- 向上转型:父类的引用指向子类的对象(子类的对象赋值给父类的引用)
- 向下转型:使用强制类型转换符
- 引出:有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法,但是由于变量声明为父类类型,导致编译时只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用
Man m = (Man)p;
-
instanceof关键字的使用:
- 判断a对象是否是A类的实例。是返回true,否则返回false
7、Object类的使用
- 说明:
- Object类是所有Java类的根父类
- 如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object
- Object类中的属性、方法具有通用性
- 属性:无
- 方法:equals( ) toString( ) …
- equals( )和 “” 区别:
- “==”运算符:
- 可以使用在基本数据类型和引用数据类型变量中
- 如果比较的是基本数据类型变量:比较两个变量保存的数据是否相等
- 如果比较的是引用数据类型变量:比较两个变量的地址值是否相等
- equals()方法的使用:
- equals()是方法,不是运算符
- 只能适用于引用数据类型
- Object类中定义的equals()和 “==”的作用是相同的:比较两个对象的地址值是否相同
- 像String、包装类这些类都重写了Object中的equals()方法,这是比较的就是“实体类中的内容”,而不是地址值
- toString( )的使用
- Object类中的toString()方法返回的是类名和它的引用地址
- 用户可以自定义类中重写toString()方法
8、包装类的使用
- 包装类的使用:
- Java提供了8种基本数据类型对应的包装类,使得基本数据类型的变量具有类的特征
- 基本数据类型、包装类与String之间的转换:
- 基本数据类型----->包装类:调用包装类的构造器
- 自动装箱:
- 包装类----->基本数据类型:调用包装类的xxxValue()
- 自动拆箱:
- 基本数据类型、包装类------>String类
- 方式1:连接运算:String str = num1 + “ ”
- 方式2:使用String类的valueOf()方法
- String类------>基本数据类型、包装类
- 方式:parseXxx()
- 基本数据类型----->包装类:调用包装类的构造器
面向对象(下)
1、关键字:static
- static的使用:
- static:静态的
- static可以用来修饰:属性、方法、代码块、内部类
- 使用static修饰属性:静态变量
- 属性按是否使用static修饰,又分为:静态变量 VS 非静态属性(实例变量)
- 实例变量:创建了类的多个对象,每个对象都有独立拥有一套非静态属性,当修改其中一个对象的非静态属性时,不会修改到其他对象的属性
- 静态变量:创建了类的多个对象,多个对象共享一个静态属性。修改一个对象的静态属性时,会导致其他对象的该静态属性被修改
- static修饰属性的其他说明:
- 静态变量随着类的加载而加载,可以通过"类.静态变量"的方式调用
- 静态变量早于对象的创建
- 由于类只会加载一次,所以静态变量在内存中只存一份:存在方法区的静态域中
调用 | 类变量 | 实例变量 |
---|---|---|
类 | yes | no |
对象 | yes | yes |
- 使用static修饰方法:静态方法
- 随着类的加载而加载,可以通过"类.静态方法"的方式调用
- 静态方法中只能调用静态方法、静态属性
- 非静态方法中既可以调用静态方法或属性;也可以调用非静态方法或属性
- static注意点:
- 在静态的方法内,不能使用this关键字、super关键字
- 静态属性、静态方法和类是同生命周期
- 如何确定一个属性或方法是否需要用static修饰
- 属性可以被多个对象所共享,不会随着对象的不同而不同的
- 工具类中的方法习惯定义成静态方法
- 操作静态属性的方法,通常设置成static的。比如:Math、Arrays、Collections
- 拓展:单例设计模式
- 定义:所谓类的单例设计模式,就是采取一定的方法保证在整个软件系统中欧,对某个类只能存在一个对象实例
- 饿汉式步骤:
- 私有化类的构造器 private Order(){ }
- 内部创建类的对象 private static Order order = new Order();
- 提供公共的静态方法,返回类的对象 public static Order getInstance(){ }
- 要求此对象也必须声明为静态的
- 懒汉式步骤:
- 私有化类的构造器 private Order(){ }
- 声明当前类对象,没有初始化 private static Order order = null;
- 声明public、static的返回当前类对象的方法 public static Order getInstance(){ if(order == null) {order = new Order();} }
- 区分:
- 饿汉式:坏处:对象加载时间过长 好处:线程安全
- 懒汉式:好处:延迟对象的创建 坏处:线程不安全
2、理解main方法的语法
main( )方法的使用说明:
- main()方法作为程序的入口
- main()方法也是一个普通的静态方法
- main()方法可以作为与控制台交互的方式
3、类的成员之四:代码块
- 代码块的作用:
- 用来初始化类、对象
- 只能使用static修饰
- 分类:
- 静态代码块:
- 内部可以有输出语句
- 随着类的加载而执行,而且只执行一次
- 初始化类的信息,如类的静态属性
- 如果一个类中定义了多个静态代码块,则按声明的先后顺序执行
- 静态代码块的执行要优于非静态代码块的执行
- 静态代码块中可以调用静态属性、方法,不能调用非静态的结构
- 非静态代码块:
- 内部可以有输出语句
- 随着对象的创建而执行
- 每创建一个对象,就执行一次
- 可以在创建对象时,对对象的属性进行初始化
- 如果一个类中定义了多个非 静态代码块,则按声明的先后顺序执行
- 非静态代码块内可以调用静态属性、方法、非静态属性、方法
- 静态代码块:
总结:对属性可以赋值的位置
- 默认初始化
- 显示初 始化/在代码块中赋值
- 构造器中初始化
- 有了对象之后,可以通过“对象.属性”或“对象.方法”的方式,进行赋值
4、关键字:final
- final的使用:
- final:最终的
- final可以用来修饰的结构:类、方法、变量
- final用来修饰类:此类不能被其他类所继承 例如:String、System、
- final用来修饰方法:表明此方法不能被重写 例如:Object类中的 getClass()
- final用来修饰变量:此时的“变量”就称为常量
- static final:用来修饰属性:全局常量
5、抽象类和抽象方法
- abstract关键字的使用:
- abstract:抽象的
- abstract可以用来修饰的结构:类、方法
- abstract修饰类:抽象类
- 此类不能实例化
- 抽象类中一定有构造器,便于子类实例化时调用
- 开发中都会提供抽象类的子类,让子类对象实例化,完成相关的操作
- abstract修饰方法:抽象方法
- 抽象方法只有方法的声明,没有方法体。
- 包含抽象方法的类,一定是抽象类。反之,抽象类中可以没有抽象方法。
- 若子类重写了父类中的所有的抽象方法后,此子类方可实例化。
- 若子类没有重写父类中所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
- 注意点:
- abstract不能用来修饰:属性、构造器等结构
- abstract不能用来修饰私有方法、静态方法、final修饰的方法、final的类
- 抽象类的匿名子类的使用:
//Person是抽象类
Person p = new Person() {
public void method(){ };
}
- 多态的应用:模板方法设计模式
6、接口
- 接口的使用:
- 接口使用interface定义
- Java中,接口和类是并列的两个结构
- 如何定义接口:
- JDK7及以前:只能定义全局常量和抽象方法
- 全局常量:public static final的,但是书写时可以省略
- 抽象方法:public abstract 的
- JDK8:除了定义全局常量和抽象方法之外,还能定义静态方法、默认方法
- 接口中的静态方法,只能通过接口去调用
- 通过实现类的对象可以调用默认方法;
- 如果实现类中重写了接口中的默认方法,调用的是重写后的默认方法
- 如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的默认方法,那么子类在没有重写此方法的情况下,调用的是父类中同名同参数的默认方法(类优先原则)
- 如果实现类实现了多个接口,而多个接口中定义了同名同参数的默认方法,那么在实现类没有重写此方法的情况下,报错。
- 所以必须在实现类中重写此方法
- 如何在子类(实现类)的方法中调用父类、接口中被重写的方法。例如:接口名.super.方法名()
- 接口中不能定义构造器,所以接口不能实例化
- Java开发中,接口通过让类去实现(implement)的方式来使用
- 如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化
- 如果实现类没有覆盖接口中所有的抽象方法,则此实现类仍为一个抽象类
- Java类可以实现多个接口
- 弥补了Java单继承性的局限性
- 格式:class AA extends BB implement CC,DD,EE
- 接口和接口直接可以继承并可以多继承
- 接口的具体使用,体现多态性
- 接口,实际上可以看做是一种规范
- 接口的应用:
- 代理模式
- 工厂模式
- JDK7及以前:只能定义全局常量和抽象方法
7、类的成员之五:内部类
- 内部类的定义:
- Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B就是外部类
- 分类:
- 成员内部类:
- 静态内部类、非静态内部类
- 一方面,作为外部类的成员
- 可以调用外部类的结构
- 可以被static修饰
- 可以被4中不同的权限修饰
- 另一方面,作为一个类
- 可以定义属性、方法、构造器
- 可以被final修饰,表示该类不能被继承,不适用final就可以被继承
- 可以被abstract修饰
- 局部内部类:
- 声明在方法内、代码块内、构造器内
- 关注点:
- 如何实例化成员内部类的对象
- 如何在成员内部类中区分调用外部类的结构
- 开发中局部内部类的使用
第五章:异常处理
1、异常的概述与异常体系结构
-
异常定义:
- Java语言中,将程序执行中发生的不正常情况称为“异常”。
-
异常的分类:
- Error: Java虚拟机无法解决的问题
- Exception: 其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码处理
-
异常体系结构:
Java.lang.Throwable
|---------------------------Java.lang.Error
|---------------------------Java.lang.Exception
|---------------------------编译时异常(checked)
|----------IOException
|----------ClassNotFoundException
|---------------------------运行时异常(unchecked)
|----------NullPointerException
|----------ArraryIndexOutOfBoundsException
|----------ClassCastExceptioon
|----------NumberFormatException
|----------InputMismatchException
|----------ArithmeticException
2、常见异常
常见的异常:
- Java.lang.RuntimeException
- ClassCastException
- ArrayIndexOutOfBoundsException
- NullPointerException
- ArithmeticException
- NumberFormatException
- InputMismatchException
- Java.io.IOExeption
- FileNotFoundException
- EOFException
- Java.lang.ClassNotFoundException
- Java.lang.InterruptedException
- Java.io.FileNotFoundException
- Java.sql.SQLException
3、异常处理机制一:try-catch-finally
-
异常的处理:抓抛模型
-
过程一:“抛”
- 程序在正常执行的过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象,并将出异常抛出,一旦抛出对象后,其后的代码就不再执行。
- 关于异常对象的产生:
- 系统自动生成的异常对象
- 手动的生成一个异常对象,并抛出(throw)
-
过程二: “抓” 可以理解为:1、try-catch-finally 2、throws
try-catch-finally的使用:
try{
// 可能出现异常的代码
}catch(异常类型1 变量名1) {
// 处理异常的方式1
}catch(异常类型2 变量名2){
// 处理异常的方式2
}catch(异常类型3 变量名3){
// 处理异常的方式3
}
. . . . . .
finally {
// 一定会执行的代码
}
- 说明:
- finally是可选的
- 使用try将可能出现异常代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此对象的类型,去catch中进行匹配。
- 一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常的处理。一旦处理完成,就跳出当前的try-catch结构(在没有写finally的情况),继续执行其后的代码。
- catch中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下无所谓;catch中的异常类型如果满足子父类关系,则要求子类一定声明在父类上面,否则报错。
- 常用的异常对象处理的方式:1、String getMessage() 2、printStackTeace()
- 在try结构中声明的变量,在出了try结构以后,就不能在被调用
- 体会:
- try-catch-finally结构可以将一个编译时异常延迟到运行时进行处理。
- 开发中,由于运行时异常比较常见,所以我们通常就不针对运行时异常编写try-catch-finally了;针对于编译时异常,我们说一定要考虑异常的处理。
- finally的使用:
- finally是可选的
- finally中声明的是一定会被执行的代码。即使catch中又出现异常了,try或catch中有return语句等情况。
- 如数据库连接、输入输出流、网络编程等资源,JVM是不能自动回收的,我们需要自己受到回收释放,此时的资源释放就需要声明在finally中。
4、异常处理机制二:throws
- 使用方式:
- “throws + 异常类型” 写在方法的声明处。指明此方法执行时,可能会抛出的异常类型。一旦当方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足throws后的异常类型时,就会被抛出。异常代码后续的代码,就不再执行。
- 体会:
- try-catch-finally:真正的将异常给处理掉了。
- throws的方式只是将异常抛给了方法的调用者,并没有真正的将异常处理掉。
- 开发的过程中如何选择使用try-catch-finally还是使用throws:
- 如果父类中被重写的方法没有throws方式处理异常,则子类重写的方法也不能使用throws,意味着如果子类重写的方法中有异常,必须使用try-catch-finally方式处理。
- 执行的方法A中,先后又调用了另外的几个方法,这几个方法是递进关系执行的。我们建议这几个方法使用throws的方式进行处理。而执行的方法A可以考虑使用try-catch-finally方式进进行处理。
- 重写方法异常抛出的规则:
- 子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型
5、手动抛出异常:throw
- 使用方式:
- throw new Exception(); 手动生成一个异常对象
6、用户自定义异常类
- 如何自定义异常类:
- 继承于现有的异常结构,RuntimeException、Exception
- 提供全局常量:serialVersionUID
- 提供重载的构造器