---------------------------------------------面向对象4天-------------------------------------------------------
Day01:
static关键字 静态
修饰成员变量和方法
成员变量不是私有的(没有用private修饰)不用有getXxx/setXxx方法
1.让成员变量被所有的对象所共享,不属于任何一个对象;
2.被修饰的成员变量可以直接类名点调用;
3.随类的加载而加载,优先于对象;
**** 静态是什么时候加载
是跟随类的加载而加载,类加载了就可以直接使用了,是优先于对象
对象的创建:
1. 类加载到内存中(已经加载静态成员变量、方法)
2. 创建对象
是什么时候使用
类加载完毕就可以使用
静态成员方法:
工具类
静态成员变量:
所有对象共享一个成员变量
注意事项:
非静态:
1.可以调用静态和非静态方法和变量
静态:
1.只能调用静态方法和静态成员变量
原因: 静态是随类的加载而加载,非静态是随对象的创建而产生,有静态的时候还没产生非静态。
利弊:
优点:
1.节省空间、不用存储多个相同变量
2.不能创建对象、节约堆内存
弊端:
1.局限性,只能调用静态成员方法和静态成员变量。
工具类:
1.私有化构造方法
2.静态成员方法以及变量
代码块
局部代码块:
位置:方法中
执行:方法调用的时候执行
作用:控制变量生命周期
构造代码块:
位置:类中、方法外、构造方法平级
执行:每次创建对象,构造代码块执行一次
作用:提取构造方法中的共性
静态代码块:
位置:类中、方法外、构造方法平级
执行:类加载的时候,执行一次
作用:类开始加载的时候需要初始化操作的代码块可以放入静态代码块
**** 了解代码块执行顺序;先静态代码块 再构造代码块(构造方法共性,所以优先于构造构造方法) 最后局部代码块(构造方法内的代码块)
拓展
设计模式(总计23种):
就是前人总结出来的一些特定问题的套路
**** 单例设计模式:
1.饿汉式(开发中常用)//在一个私有静态构造方法中创建类对象:私有是不对外,静态是随类的加载而运行一次 再创建一个静态方法返回对象
2.懒汉式 //再成员方法位置用静态构造声明对象, 再创建一个类来返回对象,类里面判断如果对象==null,就创建对象。返回创建对象之后的对象。
冒泡排序
两个for循环嵌套,每次循环确定一个数,用第一个数去比较所以少比较一次
薄弱点:标记求不重复随机数存数组
Day02:
继承
定义:多个类,有共同的成员变量和成员方法,抽取到另外一个类中(父类),再让多个类继承这个父类,这时候多个类就可以获取到父类中的成员了。
extends 父类;
特点:
1.一个类只能继承一个父类,单一继承;
2.一个类可以多层继承,一个儿子可以有个亲爹,还可以有个亲爷爷;
3.类的继承要有所属关系,不要随便去继承一个类;
成员变量
特点:
**** 1.子类只能获取父类非私有成员;private修饰的
2.子父类中成员变量名字不一样,就直接获取想获取的
3.如果子父类中成员变量名字一样,获取子类成员变量
就近原则:
**** 1.谁离我近我就用谁;
2.先局部变量,再子类成员变量,最后父类成员变量;
**** super:可以获取父类的成员变量和成员方法,用法和this相似;
成员变量属于对象的。 所以要调用成员变量要用 this.成员变量名
成员方法
特点:
1.子类中没有这个方法,就调用父类的;
2.子类中没有重写这个方法,调用父类的;
**** 方法的重写:在子父类中,子类的方法和父类的一样(完全一样),子类重写了父类的方法(覆盖、复写);
原因(使用场景):父类方法不能完全满足子类,子类可以重写父类的方法。
@Override //注解 检查子类方法是否重写父类的方法,以后凡是重写父类方法都加此注解,这个阿里巴巴开发规范;
注意事项:
父类方法是私有的,子类无法重写方法,也无法继承这个方法;
方法的重载:再一个类中有个重名的方法,参数不一样(个数,类型,顺序),无关;
Overload
super、this 使用位置:子类中
1.有static 不能有super、this 原因:static随类的加载而加载。在类加载的时候 没创建对象就没有super、this
2.子类的访问权限要大于等于父类的访问权限(重写方法的访问权限 public private)
构造方法的执行顺序:
1.在有子父类继承关系的类中,创建子类的对象,调用子类的构造方法
2.如果子类构造方法第一行代码,没有调用父类的构造方法,则会默认调用父类的无参构造。
3.肯定会先执行父类的构造方法,因为先要给父类的成员变量进行初始化,子类可能会用到;
总结:现有父再有子,创建子类对象必定先执行父类构造;在构造方法中调用构造方法,必须在代码的第一行;默认会super();
this和super区别:
this:当前类的本类对象引用;哪个对象调用此方法,那么方法中的this就代表那个对象
this可以调用本类的成员方法和成员变量;
this可以在构造方法中调用本类其他构造方法
super:本类对象中父类的资源;
super可以调用父类的成员
super可以在构造方法中调用父类的构造方法;
继承的优缺点:
优点:
1.提高了代码的复用性(简化代码书写)
2.增强了可维护性;
缺点:
1.让代码的耦合性增强了;类与类之间的关系;
匿名对象:
就是new Student();
没得名字的对象;
应用场景: 当方法只调用一次的时候,可以使用匿名对象;
可以当做参数进行传递,但无法在传参之前做其他事情;
匿名对象可以调用成员变量,但是没有意义;
final 关键字;
修饰符:最终的意思
可以修饰类、成员方法、成员变量;
注意事项:
1.final修饰的类,不能被继承,不能有子类;
2.final修饰的方法,不能被重写。
3.final修饰的变量就是常量;(自定义常量名称必须为字母大写COOL_BOAY,必须初始化)
抽象类
abstract 修饰符修饰的类和方法
抽象方法:
当父类不能明确子类的具体需求,可以把父类中的这个方法定义成抽象。
不同类的方法是相似的,但是具体内容又不太一样,所以我们只能抽取他的声明
没有具体的方法体,没有具体方法体的方法就是抽象方法;
**** 抽象类:(提取完全的共性,优化可维护性)
特点:
1.有抽象方法的类必须是抽象类;
2.抽象方法和抽象类必须用abstract修饰;
3.抽象类不能创建对象(不能实例化);
4.抽象类中可以有非抽象的方法;
5.抽象类和类的关系也是继承,一个类继承抽象类,要么重写所有抽象方法,要么自己是抽象类;
抽象类中的构造方法
可以用来给抽象类中的成员变量初始化;
子类创建对象都会默认访问父类的空参构造;
抽象类中的非抽象方法:可以给子类使用;
abstract 不能和那些关键字共存
1.static关键字 static随类的加载而加载。 abstract修饰的方法,没有方法体,加载没有意义;
2.final关键字 final修饰的方法,不能被重写。
3.private关键字 因为私有方法之后,只有本类才能识别,子类不能识别到,不能重写。
注意事项: 一个类继承了一个抽象类,必须重写父类所有的抽象方法;否则这个类就得是抽象类;
大白话:就是一个父类的抽象类的抽象方法子类也没具体方法体表现,不重写抽象方法的办法就是子类也定义成抽象类;
抽象思想:
Writer FileWriter
作为父类不能明确子类具体该如何实现功能,所以方法只能抽象;
作为Writer的子类,是一个输出流,就必须具备写数据的功能,在Writer中定义了写数据的抽象方法,那么子类就必须重写自己的功能,起到规范作用;
day03
接口:用于处理继承的单一继承的局限性;
格式:interface 接口名{}
成员特点:
1.只有抽象方法、以及常量(有默认修饰符 public static final)
2.只能用public、abstract修饰
3.有默认的 public abstract
建议:手动加上public abstract 是规范;
接口与接口关系:
1.继承关系,而且多继承。 interface Dog extends Animal,DogAnimal
接口的思想:
就是定义规则;
向上抽取过程中,如果父类不知道子类具体如何实现,定义抽象,如果所有的方法都是抽象,这个时候,这个类定义为接口;
例:
ArrayList 数组 LinkedList 链表 实现完全不同,只能在父类中提取方法声明,抽取方法,如果都是抽象方法,这个类就可以定义为接口;
学习了最顶层功能,虽然不知道子类具体怎么实现,但是只要创建子类对象就可以使用;
接口的优点:
1.打破了继承的单一继承的局限性
2.对外提供了规则;
3.降低了程序的耦合性(实现模块化开发,每个人负责一个模块,提高了开发效率)
接口与抽象类的区别:
1.与类的关系
2.成员的区别
多态
前提:1.子父类继承关系
2.方法重写
3.父类指向子类对象
动态绑定:
1.运行期间 成员变量:使用父类
成员方法:检查子类,子类重写方法了,那么久运行子类,根据传递对象判断调用子类 还是父类 方法;
静态方法:不存在重写概念;编译检查父类,运行使用父类
2.编译期间 检查父类(因为编译期间还没对象)
定义:多种形态,
向上转型
Animal a = new Cat();
向下转型
Cat c = (Cat)a;
多态的优缺点:
缺点:多态的形式创建对象,不能直接使用子类的特有成员;
优点:提高了代码的可扩展性;可维护性(多态前提保证的————继承)
例子:
方法的参数上,如果类型是具体的子类就只能传递子类对象。
如果方法的参数是父类类型,那么可以传递所有的子类对象;
拓展
多态:
优点:代码可扩展性
缺点:不能直接访问子类特有成员,要向下转型
接口:
优点:降低类与类之间的耦合性;
打破单一继承的局限性;
定制规则;
Day04
包:
作用:分类管理Java文件;
特点:1.可以有多层
2.不同包下Java文件名可以重复
3.包的声明必须是第一行代码
不同包之间访问:
使用类的全名;
用关键字import将类导入
权限修饰符
public 公共的 //当前类可以访问、 同包不同类可以访问、 不同包不同类可以访问
default 默认的 //当前类可以访问、 同包不同类可以访问
protected 受保护的 //当前类可以访问、 同包不同类可以访问、 不同包的子类对象可以访问
private 私有的 // 当前类能访问,出了当前类,只能用setXxx、getXxx访问
内部类(虽然在类当中,但是编译的时候有单独的class文件)
成员内部类:在类中,和方法平级创建一个新类;
使用场景:
在平级方法里创建对象,可以调用内部类的方法;
内部类可以调用外部类成员,private修饰的成员也可以调用;
在同包不同类中调用内部类:
导入外部类;
外部类.内部类
局部内部类:(在成员方法中的类)
使用场景:在成员方法内,出了方法就无法使用;
在方法内,声明局部内部类之后 才能使用;
匿名内部类: (就是一个没有名字的局部内部类) 位置:成员方法中;
<没有名字就不能被调用,不能创建对象>所以定义内部类就必须创建内部类的对象;
使用场景:
作为参数进行传递;
接口和抽象类不能创建对象,匿名内部类解决了这个问题;
前提:必须有父类或者父接口
定义匿名内部类做了两件事:一个是定义一个子类;二个是创建了子类的对象;
格式: new 类/接口(){
// 这是一个 类/接口 的子类
重写方法体;
};
匿名内部类在方法内,方法运行完,如果没有其他引用指向匿名内部类,那么匿名内部类会被垃圾回收机制回收;和变量一样会消失。
其实就是:局部变量和匿名内部类的生命周期不一样;
内部类的修饰符:
1.权限修饰符 //访问范围
2.static修饰 //创建对象发生变化而已,静态方法(内部类)可以类名点 调用 ;
3.abstract、final修饰
内部类优点;
可以直接访问外部类的成员,包括私有的成员;
-----------------------------------------------Object类中常用关键字---------------------------------------------------
day05
学习新的一个类或者接口 都可以查询文档来学习 JDK API 1.6.0中文版
API Java提供的类
Object类:
所有类的根类(超类),任何类(包括对象和数组)都直接或间接的继承Object;
方法:
String toString(); 返回该对象的字符串表示; return getClass().getName() + "@" + Integer.toHexString(hashCode())
输出一个对象就是默认输出这个对象的父类的toString()方法;
getClass()谁调用就返回哪个类的class文件
getName()返回class文件的类名
Integer.toHexString(Object o)返回指定参数的十六进制字符串类型
hashCode() 返回该对象的哈希码值(内存地址)
toString();是返回对象的十六进制内存地址值;
因为父类toString();方法不能满足子类需求;
所以我们通常都是重写toString()方法; //调试、测试、学习使用,开发用的比较少;
boolean equals(Object o);比较两个对象是否相等;也是Object类下的方法,不重写父类方法比较的是两个对象地址值;
不比较对象的内存地址,而是比较对象的每个属性值是否相等,怎么办呢?
重写equals方法
System类
java.lang包,不用导包可以直接使用;类字段就是静态成员变量,属于对象;不能实例化就是抽象类,构造方法也被私有化了;
复制数组
arrayCopy(Object src , int srcPow , Object dest , int destPow , int length):
scr:源数组
srcPow:源数组的起始索引位置
dest:目标数组(接收复制过来的数据)
destPow:目标数组起始索引位置
length:指定接收的元素个数
运用:可以灵活复制数组 System.arrayCopy(src,0,dest,0,5);
以毫秒值返回当前系统时间;这毫秒的时间是相对时间,相对于1970-1-1 00:00:00
1000毫秒 = 1秒
currentTimeMillis():
运用场景:
1.测试程序执行效率;
终止虚拟机
exit():0代表正常,非0代表异常
运行垃圾回收器
gc():尽最大努力从丢弃的对象中回收空间;
Date类 java.util包 要导包;
表示特定的瞬间,精确到毫秒;
非静态方法,需要创建对象才能调用;
构造方法
Date(): 创建的是一个表示当前系统时间的Date对象
Date(long date): 根据指定时间(是毫秒值)创建Date对象
long date:是用1970-1-1 0:0:0到现在的毫秒值 + long date 返回加上long date 的毫秒值
成员方法:
常用的 毫秒值 --- Date
setTime(long time)
设置 以1970-1-1为基数 +- long time;
返回值void,参数long
Date --- 毫秒值
getTime()
获取
返回值long,无参数
DateFormat类 java.text 包下 要导包
格式化时间的类(是抽象类)
两种方法使用:
1.创建子类对象,调用;
2.直接类名点调用静态方法;
SimpleDateFormat类: 日期的格式化 和 解析 类 设置时间的模具!!!
格式化:
Date --- String
String format(Date date)
解析:
String --- Date
Date parse(String source)
SimpleDateFormat类的构造方法:
SimpleDateFormat();使用默认的模式进行对象的构建
SimpleDateFormat(String pattern):使用指定的模式进行对象的构建
解析的字符串,模式必须和默认的模式相同;
Calendar 日历类 abstract类 抽象类 不能直接创建对象,有个静态方法 toInstance(); 调用这个方法间接的创建了子类对象;
功能:提供了一些操作 年 月 日 时 的方法;
获取功能 int year = get(Calendar.YEAR); 月份从0月开始的 要+1;
修改功能 void set(Calendar.YEAR , int value); 要修改的项目, 修改值
添加功能 void add(Calendar.YEAR , int amount); 要添加的项目, + 添加值
API
引用类型:(包装类)
基本类型只能参与一些运算,包装类就是把基本类型的功能进行增强;
byte ------ Byte
short ------ Short
char ------ Character
int ------ Integer
long ------ Long
float ------ Float
double ------ Double
boolean ------ Boolean
Integer:
String --- int
1.创建Integer 对象 调用 int i = Integer.intValue()
2.使用静态方法 int i = Integer.parseInt(String s);
int --- String
1.+“” 拼接
2.使用静态方法 Integer.toString();
-----------------------------------------------集合---------------------------------------------------
Day06
集合 --- 学顶层 用底层 : 顶层是接口全是抽象方法,子类全都要实现方法,顶层有的方法底层肯定有;
最顶层的根(接口) : Collection
一级子类: List
二级子类: ArrayList
Collection中的常用功能:
提取所有集合类的共性:
1.添加元素 add
2.清空集合 clear
3.判断是否为空 isEmpty
4.删除 remove
5.大小 size
6.集合转成数组 toArray
1.toArray是把集合转成Object[]类型数组
2.如果要使用其他类型数组的特有方法,不能直接强转数组 --- 容器不能强转
3.只能强转Object中的每个元素,在调用其他类型的特有方法;
迭代器
iterator() 可以返回一个迭代器;其实就是用来遍历集合的;
父类是一个接口 Iterator
方法:
Iterator it = c.iterator();
it.next();//获取下一个元素,返回值是Object类型元素,如果没有元素可以获取,会报错没有元素获取异常;
hasNext();//判断是否有元素可以获取,返回值是boolean类型 可以用while()循环;
遍历集合方法:
1.toArray()
2.迭代器 集合对象.iterator()
并发修改异常:
概念:在迭代器获取元素(遍历)的过程中,如果对集合的元素进行添加或者删除(set修改不会出现并发修改异常),有可能就会出现并发修改异常
迭代器是依赖于集合的,相当于集合的一个副本,当迭代器在操作的时候,如果发现和集合不一样,则抛出异常;
解决方法:
使用迭代器遍历的时候,使用迭代器进行修改
ListIterator lis = list.listIterator();
lis.add'
lis.remove'
泛型:
就是指定集合的类型;
优点:将明确类型的操作提前到了编译期;
减少了代码的书写
避免了类型转换异常的问题
减少了一些黄色警告
foreach(加强for循环)
用于遍历【集合】 或者 数组
格式:
for(数据类型 变量 : 集合或者数组){
可以直接使用变量;
}
注意:在增强for循环中,如果添加或者删除集合中的元素 会出现并发修改异常; 因为增强for底层就是迭代器;
常见的数据结构:(集合的底层结构)
数组:
长度不可变
元素都有整数索引
只能存储同一类型的元素
可以存基本数据类型,也可以存储引用数据类型
查找快(因为每个元素有索引)、增删慢(长度不可变,要创新数组来接收);
链表:
由链子连接起来的一堆结点;
结点:地址值,值是下一个结点的地址值
查询慢(从头开始找),增删快(调节结点就行了)
栈和队列:
栈:先进后出 入口出口相反
队列:先进先出 入口出口一顺风
List子体系:Collection的子体系 是接口;
特点:
1.有序(存储和读取顺序是一致的)
2.有整数索引
3.允许重复的
特有方法:
1.add(index,element) //指定位置添加元素element 返回值void 因为可以重复所以都是添加成功;
2.get(index) //获取指定索引的元素; 返回值 是获取元素类型
3.remove(int index) //删除指定索引元素 返回值 是删除的元素
4.set(index,element) //修改指定索引元素 返回值 是修改的元素
ArrayList和LinkedList
ArrayList(底层是数组结构):查询快、增删慢
查询多,增删少就用ArrayList
未知:就用ArrayList
LinkedList 是个普通类(底层是链表结构):查询慢、增删快
查询少、增删多就用LinkList
特有功能:都要返回操作的元素
1.addFirst() //将元素添加到集合索引为0的位置
2.addLast() //将元素添加到集合索引为size() - 1的位置
3.getFirst() //获取集合第一个元素
4.getLast() //获取集合的最后一个元素
5.removeFirst() //删除集合第一个元素
6.removeLast() //删除集合最后一个元素
Day07
HashSet和HashMap
Set体系
是collection接口的子接口;
HashSet是接口Set的实现类:间接实现了collection的所有方法;
HashSet特点:
1.HashSet是无序的,元素存储和取出顺序有可能不一样;
2.元素是不可以重复的。
3.是没有索引的
添加元素只有一个add(Object obj);不能添加指定索引的元素add(int index,Object obj)
遍历HashSet集合
1.增强for
2.迭代器
3.转数组
HashSet存储自定义对象,并有没有实现我们想要的去重复;
拿新添加的元素和已经存在的元素进行比较:
1.比较hash值
2.比较地址值
3.比较元素是否一样
如果都是true就返回
如果有false就添加
自定义一个去重规则的set集合方法
存储对象;
1.如果就用以前的规则,每个对象的hash值是不一样的。所以只要添加新new出来的对象就会添加成功
2.这个规则不满足我当前需求,那么我们就重写这个方法
3.在这个对象中重写hasCode的方法。让其返回值都是一样的,然后去比较后面的equals
4.equals是传经来的Object类型的。需要强制转换为对象类型
5.然后比较传进来的值是否已经存在
HashMap实现类 是Map的实现类
Map与Collection没有直接关系
Map是集合的另外一个根接口
Map的常用功能
clear() 清空所有的键值对
remove() 根据key删除键值对 ,并且返回删除的value值,如果没有删除成功就返回null;
containsKey(Object obj) 判断key obj是否存在
containsValue() 判断value是否存在
entrySet()
get(key) 根据键 获取 对应的 value;
isEmpty() 判断是否有键值对存在;
keySet()
put()将key映射到value,如果key存在,就覆盖以前value,返回值是以前的value
size() 获取集合中有好多对键值对;
HashMap的遍历方法:
1.keySet() 以Set集合的形式返回所有的键
2.values() 以Collection集合的形式返回所有的值
3.entrySet() 面向对象的方式遍历
今日疑点:
1.Collections工具类的方法
2.正则表达式去除不同类型方法
3.Map集合的常用功能
4.斗地主模拟发牌以及排序 |
|