第13次课
1、回顾
this关键字:代表当前对象的引用
this.成员
static 关键字
修饰类、成员变量、成员方法
2、java中三个代码块:静态代码块、构造代码块(基本不用)、局部代码块(基本不用)
静态代码块:
static {
//代码块
}
静态代码块的特点:
当类被加载时,随着类的加载而执行的代码,静态代码块只会执行一次(JVM加载类只会加载一次)
总结:
静态代码,会在构造代码块前执行。随着类的加载而执行
构造代码块:
格式:{
}
特点:创建对象时,随着构造方法的调用,在构造方法中代码没有执行之前,存在
隐式三步:
第一步:执行super语句
第二步:显示初始化非静态成员变量
第三步:执行构造代码块
小结:构造代码块,在创建对象的时候,会执行一次(每创建一个对象,就执行一次),先于构造函数执行
局部代码块:
类和对象的加载过程
JVM启动,会去方法区找Test.class
类加载:
jvm启动时,会去方法区找这个类,不错在就会加载
到方法区里面:
先加载非静态的成员(构造函数),再加载静态成员;
加载静态成员变量的时候,先初始化默认值,再显示初始值
加载显示完成之后,就会执行静态代码块
创建对象加载:
1、 new 就会开辟空间并分配一个内存地址
2、 开辟完成之后,就会把类中的所有非静态成员加载到开辟的堆内存
中,
3、然后默认进行初始化
4、在调用构造方法的时候存在隐藏的三步操作:
1 执行super
2 显示非静态成员的初始值
3 执行构造代码块
执行构造方法里面的代码,执行构造方法完成之后,构造方法出栈。
继承
关键字:extends
特点:父类私有化的成员是无法被继承的;
小结:使用extends关键字,私有成员(private)不能继承
父类:基类、超类
子类:派生类
注意:java关键字extends,继承关系必须符合,is-a(一类是一个事物的)
java 语言只支持单一继承,不支持多继承;
不支持多继承的原因:
当多个父类总存在相同的功能时,子类继承了父类的功能
但是子类去调用父类中相同的功能时候,就会无法判断调用哪一个
造成调用的不确定性。
Lesson14
继承中成员的特点:
成员变量:
1.当父类与子类中存在相同的成员变量时,子类调用该变量名时,会优先调用子类中的变量名;
2.不建议在子类中定义与父类相同的成员变量
3.如果存在相同的,要使用父类中的成员
成员方法:
重写
当子类与父类存在一模一样的方法,就叫重写。
特点:会让程序的扩展性与维护性变得更好
方法(函数)的特点:
重载
发生在同一个类中
方法名相同、参数列表不同和返回值类型无关
重写
发生在子类父类中(继承中)
方法名相同,参数列表相同,返回值相同
重写的好处:
1.提高程序的复用性、扩展性、后期维护。
this和super区别
相同点:都是用来引用对象的。
不同点:this是用来引用当前对象
super是引用父类对象
重写注意细节:
1、父类中的方法如果是private,不参与子类方法的重写(子类中不能重写父类中的private修饰的方法)。
Private访问权限最小,只限于本类使用,如果子类与父类中书写了一个相同的private方法时,该方法时属于本类的,和重写没有关系。
2.子类中重写方法的权限必须大于或等于父类重写的方法
3.父类中的方法时静态的,子类也必须是静态的。
final关键字
父类中的某些方法不允许子类去重写,在java中我们就使用final 关键字修饰;
格式: 访问修饰符 final关键字 返回值类型 方法名(参数列表)
注意:
加上final关键字,是代表不能重写,但是能被继承。方法的修饰是private的代表该方法不能被继承和重写。
final修饰成员变量,会变成常量。常量必须要赋值,一旦修饰为final,就不能更改了。
final修饰类,被final修饰的类不能被继承。
抽象类:
关键字:
当一个事物的功能没有具体功能体时,或者无法描述的时候,成为抽象。
抽象类的特点:
1.抽象类不能被实例化(不能创建对象);
2.子类继承抽象类,必须重写抽象类中所有的抽象方法。,后子类才能创建对象。
3.被abstract修饰的方法,必须在包含在抽象类中。(抽象类中可以写普通方法);
Lesson15
回顾
继承中成员使用
final 关键字
抽象类:abstract
抽象方法必须写在抽象类里
抽象类不能被实例化
抽象类中可以写普通方法
3、知识点
单例设计模式
所谓的设计模式其实就是经过大量的时间积累和总结,把一些问题归纳,把开发中遇到的类似问题直接套用,来解决问题。
单例设计模式主要解决的问题:
接口
关键字:interface
实现接口关键字:implement
接口中定义的变量,默认为会加上public static
特点:
1、接口中只能定义常量和抽象方法(有固定修饰符格式)
2、接口不能被实例化
3、实现接口的子类,必须把接口中的所有抽象方法全部重写后,才可以创建子对像
接口是为了多实现,子类能实现多接口,接口之间能多继承。
接口与抽象的区别:
接口中定义的全部是抽象方法,而抽象类中可以定义普通方法;
接口中定义的变量都是常量(必须赋值);而抽象中可以定义变量
接口中没有构造方法;而抽象类中有抽象方法
接口是用来描述事物功能的扩展的;抽象类是描述事物共性的内容;
接口可以多实现(解决java中只能单继承的问题);而抽象类只能单一继承。
2、多态
事物以多种形态来表现。
在java中,我们可以使用具体对象来描述
例子:Dog dog = new Dog();
具体类型 对象
也可以使用对象的父类型来描述;
Animal dog=new Dog();
注意:使用多态有个前提,必须是继承关系或者实现关系。
多提的体现:
父类(接口)的引用指向子类的对象
父类 引用变量=new 子类();
接口 引用变量=new 子类();
多态的好处:提高程序中的代码扩展性
多态的前提:
使用多态必须是继承或者实现关系
通常子类需要把父类中的方法重写
多态弊端:
只能操作父子类共有的方法,不能操作子类中特有的方法;
如何解决这个弊端:
向上转型:
之前Animal an= new Dog();
父类类型 父类引用 子类对象
使用父类引用(an)指向子类对象时,其实子类类型已经向上提升为为父类型;----向上转型
向下转型:
Animal an=new Dog();
Dog dog=(Dog)an;--------向下转型(需要强制转换)
向下转型遇见类型转换异常时,使用关键字instanceof来判断
lesson 17
1、回顾
2、适配器模式
没有抽象方法的抽象类
接口与类之间新增一个抽象类去实现这个接口,然后子类继承这个抽象类,重写子类自己需要的功能方法。
3、异常
java中存在的2种问题:异常、错误(错误比异常严重)
异常:
在程序运行中发生的异常。通过这个异常有针对性的处理方案(程序员自己写)
错误:
错误都是系统级别,通常是不会有针对性的处理方案。
通常是在书写的时候,产生JVM在操作内存上出现的问题
自定义异常
异常类需要继承相应的异常
然后书写有参数和无参数构造函数,构造函数类调用super()方法;
java中,提供了两种处理异常的方法:声明、捕获
声明:
使用关键字throws对异常进行声明(throw和throws配合使用)
使用的格式:
修饰符 返回值 方法名(参数列表) throws 异常类1,异常类2.。。
{
}
捕获:
自己处理异常
java中捕获的关键字:try catch finally
try{
}
lesson 18 API
包的概念,创建包名的规范:必须是小写(全英文),多层次包名用逗号隔开
Object类:equals方法,比较两个对象地址是否相等
String类:描述字符串的一个类,字符串是常量,存放在常量池中(方法区)
String str=”abc”;
String str=new String(“abc”);
String 是不可变的,可以共享的
2、知识点
String 方法简绍
indexof方法
null表示空对象,在使用null对象去调用String方法时就会出现空指针异常,通常采用
“”表示空字符串(不是空对象),这个字符长度为0;
lesson18
判断方法:
equals:
equalsIgnoreCase:
isEmpty:
contains:
startsWith:
endsWith:
获取方法:
length
charAt();
indexOf():
substring:
转换方法:
valueOf
toLowerCase:
toUpperCase:
切割方法:
split:
其他方法
trim:去掉字符串两端的空格
replace:替换
Math类方法(静态方法)
Math.abs
Math.ceil
Math.floor
Math.round
Math.random
lesson20
1、回顾
stringBuffer:
存储字符串的容器
特点:可以在这个容器中操作字符串
方法:添加、删除、修改、获取等方法
知识点
8大包装类
基本数据类型的包装:包装类
基本数据类型:byte short int long double float boolean char
包装类型: Byte Short Integer Double Float Blean Character
包装类的好处:更方便地操作基本数据类型
2、集合框架
数组存储特点:
长度不可变
数据类型是相同的
什么时候用到集合
存储的对象有多个的时候,可以使用容器;当存储的个数不确定时,使用集合,当存储的对象类型各不相同,也使用集合容器;
集合和数组的区别:
长度不同
元素类型不同
数组存储的元素类型相同
集合存储的元素类型可以不相同
内容不同
素组可以存储基本数据类型,也可以存储引用数据类型,但是集合存储引用数据类型(基本数据类型自动装箱)。
学习集合框架:看顶层、用底层
Collection接口
属于集合框架的顶层容器
添加、删除、获取集合中的元素、遍历
注意:Collection中不提供修改方法
添加方法
add() 添加单个元素
addAll()
remove()删除元素
clear()清除所有元素,但是对象的引用还在
contain()是否包含某个对象
size()获取元素个数
Collection带all的方法:
addAll(另一个集合的引用);
removeAll(另一个集合的引用) 删除另一个集合的元素
迭代器Iterator 接口
用来对所有集合获取元素,
next()集合的下一个元素
hasNext()判断是否还有下一个元素
集合使用细节:
集合中存储的元素其实存储的都是元素的地址
在集合中不能存储基本数据类型(JDK1.5之后自动装箱)
集合中存储的元素对象,进行存储时,全都会转为Object类型。
遍历元素时,如果需要使用集合所存储元素对象中的方法时,需要向下转型。
总结:
Collection接口
boolean add(Object obj)
boolean addAll(Collection c)
boolean remove(Object obj)
boolean size();
Iterator iterator();
Iterator 接口
Object next();
boolean hasNext();
void remove();
注意:在使用迭代器遍历集合时,不能使用集合对象去添加或者删除元素,会造成迭代不确定性。
Lesson 21
回顾 8个包装类
包装的基本数据类型
所有包装类都有个静态方法:parseXxx(String s)
集合框架
Collection接口
Collection col=new ArrayList()
删除 remove()
添加 add()
获取:Collection接口里,没有直接获取的方法
遍历:Iterator
next()
hasNext()
remove()
2、知识点
List接口
需求:在集合中获取指定位置的元素
List是Collection的子接口
List集合:有序、存储元素可以有重复、带有角标、通过角标可以操作集合中的元素
List特有的方法:
不同点:List中方法都是围绕着角标进行设计的
添加:
add(int index,Object obj)
addAll(int index, Collection c)
删除:
Object remove(int index);
修改
Object set
获取:
get(int indext)
indexOf()
subList()
特有方法:
size()
List集合的遍历
利用角标
ArrayList 类
Collection接口
List接口
ArrayList类:是List的实现类 底层存储还是使用数组结构(连续的存取空间),是大小可变的数组(新数组+复制数组)
2、查询遍历的效率比较快,增加删的效率比较慢
Linkedlist
1、底层存储结构是链表结构
2、允许有null
3、增删效率高,查询慢
特性的方法:
头尾设计:添加头、添加尾、删除头、删除尾
注意:
当我们开发的时候:不知道用什么集合对象时候:
全部使用:ArrayList集合(使用率99%)
Set接口
不可以存储重复元素、不保证存取有序(无序),只能使用迭代器来获取集合中的元素
允许存取null(只能有一个)
Set接口中子类:
HashSet类(哈希表)
实现了Set接口,底层存储的结构是哈希表(其实也是数组)结构。存储数据是无序的,允许有null元素(只能有一个)
jdk1.5之后有的:foreacher 循环(增强版for)
结构:
for(循环初始值;循环条件表达式;修改循环条件表达式){
}
for(集合或者数组中元素类型 变量名:集合或者数组){
}
foreacher是用来简化迭代器的,(只用来遍历集合或者数组)
不是所有的容器都可以使用高级for循环,只有容器实现了Iterable接口才能使用foreach循环。
泛型<数据类型>:定义集合时明确集合中所存储的元素类型
<数据类型> 只能是引用数据类型(不能是基本数据类型)
xxx.java---->编译---->运行---->发生错误(字符串异常)
我们想把运行时报的错放到编译的时就给我提示,我们就用泛型
泛型的好处:
1、可以让集合变得更安全
2、在遍历的时候不用去强制类型转换
3、运行异常转到了编译错误来处理
Lesson22
Map集合:它跟Collection是同一级别的
Collection:只能存单一的对象
开发中,经常遇到下面情况:
0---"星期天" 1---"星期一"
以前我们的查表发能解决这个问题:
String[] str={"星期天","星期一","星期二","星期三"};
str[0]="星期天";
Sunday---星期天 Monday---'星期一'
Map<K,V>集合
K表示key(键) V表示value(值) map集合存储的是一个key-value对应的对象
小结:
Collection 集合只能存储一个对象,只能存储一个对象的集合称为单列集合
Map集合可以存储两个单列集合,被称为双列集合(两个单列集合时有对应关系的)
Map集合中的基本方法:
添加
put(K key,V value)
key表示键,value表示值
当存储对象时,会按照key的名称先进行查找,没有找到相同的key,就存储value对象,并且返回是null;如果存储时,有相同的key对象已经存在map集合中,value会覆盖之前的对象,并且返回之前的对象(旧的value对象)
删除
remove(Object key)
根据指定的key值去map集合中查找到相同的key,如果没有相同的key,不执行删除操作,返回null.如果存在相同的key值,就删除相同key值对象的value的一对对象(key--value同时删除),并且返回别删除的value(旧的value对象)
修改
使用put方法进行修改
获取
get(Object key);
根据指定的key去集合中找相同的key,如果有相同的key就返回查找到key对应的value对象,如果没找到相同的key,就返回null
size(); 获取map集合中所存储的key-value对的个数
其他
isEmpty() 判断是否为空
containsKey(Object key) 根据指定的key去map集合里面判断是否有没有相同的key。有true 无 fasle
containsValue(Object value) 根据指定的value去map集合里面判断是否有没有相同的value。有true 无 fasle
Map的特殊的方法:
KeySet()方法
Map中存储的是两个对象。。是否能获取其中一个对象的所有值?可以的
key是一个单列集合,集合应该是List还是Set?
肯定是set集合,元素是不能重复的
注意:
Map集合中是没有迭代器。获取Mao集合中的元素的方法:先取出存储在map中的单列集合,在使用单列集合的迭代器进行遍历。
entrySet()方法
返回:Set<Map.Entry<K,V>>
获取map集合中存储的对应关系(映射关系),简单的来讲就是key--value
映射关系:key和value的应用关系
映射关系类型:Map.Entry
values()
获取集合中所有value的值(返回Collection)
Map集合常用的子类:
HashMap类(99%用这个)
允许nul作为key和value,但是key只能有一个null;value可以重复
properties类
属性集,存储的值都是字符串,可以利用流来对键值进行操作。(IO流会说)