封装:正确设计对象的属性和方法
原则:对象代表什么,就得封装对应的数据,并提供数据对应的行为
封装思想的好处:
继承【自己设计+用别人的】:Java中提供一个关键字extends,用这个关键字,我们可以让一个类和另一个类建立起继承关系
优点:
什么时候用继承? 当类和类之间,存在相同的内容,并满足子类是父类中的一种,就可以考虑使用继承,来优化代码
特点:
子类能继承父类中的哪些内容:
父类的构造方法不能被继承
父类中的成员变量可以被继承【非私有 private都可以 只是private修饰的成员变量不能用而已】
只有父类中的虚方法才能被子类继承
【虚方法:非private 非static 非final】
继承中成员变量的访问特点:
就近原则。现在局部位置找,本类成员位置找,父类成员位置找,逐级往上
继承中成员方法的访问特点:
同成员变量,就近原则
继承中构造方法的访问特点:
父类中的构造方法不会被子类继承,但是可以通过super调用
子类中所有的构造方法默认先访问父类中的无参构造,再执行自己
为什么?
子类在初始化之前,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据
子类初始化之前,一定要调用父类构造方法先完成父类数据空间初始化
怎么调用父类构造方法?
子类构造方法的第一行默认语句都是:super()
。不写也存在。且必须在第一行
方法重写
当父类的方法不能满足子类现在的需求时,需要进行方法重写
方法重写注意事项和要求
1、重写方法的名称、形参列表必须与父类中保持一致
2、子类重写父类方法时,访问权限子类必须大于等于父类(缺省
4、只有被添加到虚方法表中的方法才能被重写
多态:同类型的对象,表现出的不同形态
多态的前提:
多态的好处:
使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利
调用成员变量:编译看左边,运行也看左边
调用成员方法:编译看左边,运行看右边
多态的优势:
原因?
当调用成员方法的时候,编译看左边,运行看右边,在编译的时候会先检查左边类中的有没有这个方法,如果没有直接报错
解决方案:
变回子类型即可
有可能会发生转换类型与真实对象类型不一致的问题,因此在转换的时候可以使用关键字instanceof关键字判断
抽象方法:将共性的行为(方法)抽取到父类之后,由于每一个子类执行的内容是不一样的,所以,在父类中不能确定具体的方法体,该方法就可以定义为抽象方法
抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类
抽象方法和抽象类的注意事项
不能创建对象有什么用呢?当创建子类对象时,给属性进行赋值
抽象方法和抽象类的意义
强制子类必须按照这种格式进行重写
接口:就是一种规则【侧重于行为】,是对行为的抽象
接口类的注意事项
接口中成员的特点
成员变量:只能是常量 默认修饰符public static final
构造方法:没有
成员方法:在JDK7之前 接口中只能定义抽象方法默认修饰符public abstract
【只要接口中发生变化,所有的实现类都要发生变化】
【又想加新的方法,又不想报错】
JDK8以后接口中新增的方法:
允许在接口中定义默认方法,需要使用关键字
default
修饰
允许在接口中定义静态方法,需要使用关键字static
修饰
作用:解决接口升级问题
接口中默认方法的注意事项:
1、默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写的时候去掉default
关键字
2、public
可以省略,default
不能省略
3、如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写
接口中静态方法的注意事项:
静态方法不需要重写
JDK9以后接口中新增的方法:
接口中可以定义私有方法【普通的私有方法、静态的私有方法】,为了解决JDK8中允许定义的默认和静态方法有一些重复的代码需要提取出来,而提取出来的代码又不想被外界直接调用,定义私有方法
接口和类之间的关系
类和类的关系
继承关系,只能单继承,不能多继承,但是可以多层继承
类和接口的关系
实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
接口和接口的关系
继承关系,可以单继承,也可以多继承
内部类:下载一个类里面的类就叫做内部类
什么时候用到内部类?B类表示的事物是A类的一部分,且B单独存在没有意义,汽车的发动机,ArrayList的迭代器
分类:成员内部类、静态内部类、局部内部类、匿名内部类
成员内部类
静态内部类
局部内部类
匿名内部类
匿名内部类:隐藏了名字的内部类,可以写在成员位置,也可以写在局部位置
格式的细节:包含了继承或实现,方法重写,创建对象
整体就是一个类的子类对象或者接口的实现类对象
使用场景:当方法的参数是接口或者类时,以接口为例,可以传递这个接口的是西安类对象,如果实现类只要使用一次,就可以用匿名内部类简化代码
在成员内部类中,JDK16之前不能定义静态变量,JDK16之后才可以定义静态变量
静态变量
(在堆内存当中会开辟一个静态存储位置【静态区】 对象共享的,在内存当中只有一份)
static表示静态,是Java中的一个修饰符,可以修饰成员方法,成员变量
特点: 被该类所有对象共享;不属于对象属于类;静态变量是随着类的加载而加载,优先于对象出现的
调用方式:类名调用;对象名调用
静态方法
特点:多用在测试类和工具类中;JavaBean类中很少会用
调用方式:类名调用;对象名调用
static注意事项
静态方法只能访问静态变量和静态方法
非静态方法可以访问所有
静态方法中没有this关键字
this:理解为一个变量,表示当前方法调用者的地址值
super:代表父类存储空间
1、权限修饰符
2、可以修饰成员(成员变量或者方法)
3、被private修饰的成员只能在本类中才能访问
4、针对private修饰的成员变量,如果需要被其他类使用,提供相应的操作
5、提供setXxx(参数)
方法,用于给成员变量赋值,方法用public修饰
6、提供getXxx(参数)
方法,用于获取成员变量的值,方法用public修饰
final修饰方法:表明该方法是最终方法,不能被重写
final修饰类:表示该类是最终类,不能被继承
final修饰变量:叫做常量,不能被修改
细节:
就近原则:谁离我更近,我就用谁
第一个age会先在局部位置中去找,如果能找到,那么它使用的就是局部位置的age
第二个age直接使用成员遍历位置的age
this的作用:区分成员变量和局部变量
this的本质:代表方法调用者的地址值
构造方法也叫做构造器、构造函数
作用:在创建对象时,由虚拟机自动调用,给成员变量进行初始化
特点:
1、方法名要和类名完全一致
2、没有返回值类型,void也没有
3、没有具体的返回值(不能由return带回结果数据)
构造方法的定义:
1、如果没有写任何的构造方法,那么虚拟机会给我们加一个无参构造方法
2、如果定义了构造方法,系统将不再提供默认的构造方法
==号
比较的到底是什么?
1、基本数据类型:比较的是具体的数据值
2、引用数据类型:比较的是地址值
那么字符串比较应该用什么呢?
boolean equals
完全一样结果才是true,否则为false;
boolean equalsIgnoreCase
忽略大小写比较【验证码输入】
键盘输入的字符串实际上是new出来的
StringBuilder
可以看成是一个容器,创建之后里面的内容是可变的
StringJoiner
跟StringBuilder
一样,也可以看成是一个容器,创建之后里面的内容是可变的。
作用:提高字符串的操作效率,而且代码编写特别简洁,但目前市场上很少有人使用
JDK8之后才出现
直接复制会复用字符串常量池中的
new出来不会复用,而是开辟一个新的空间
基本数据类型比较数据值
引用数据类型比较地址值
等号右边没有变量
String s1 = "abc"
拼接的时候没有变量,都是字符串。触发字符串的优化机制,在编译的时候就已经是最终的结果了,会复用串池中的字符串
等号右边有变量
String s1 = "abc"
;
String s2 = "d"
;
String s3 = "ab"+s2
;
JDK8以前:系统底层会自动创建一个StringBuilder对象,然后再调用其append方法完成拼接。拼接后,再调用其toString方法转换为String类型,而toString方法的底层是直接new了一个字符串对象。
一个加号,堆内存中俩对象【StringBuilder String
】,浪费时间,浪费性能
JDK8以后:系统会预估宗福传拼接之后的总大小,把要拼接的内容都放在数组中,此时也是产生一个新的字符串。
把所有的东西都往StringBuilder
这个容器中去放,不会创建很多无用的空间,节约内存
疑问?会撑爆吗?
StringBuilder默认容量是16
默认创建一个长度为16的字节数组
添加的内容长度小于16,直接存
添加的内容大于16会扩容:2*老容量+2 = 34
如果超出扩容的容量,则以实际长度为准
默认容量
append方法
进入这个方法 :先会进行一次非空判断,如果不是null
1、先获取到现在添加的字符的长度
2、去判断是否需要扩容
进入这个方法 :
拿着3去减老容量16,小于0不需要扩容
假设需要扩容 str = “a-z” 26个英文字母
此时26-10>0,需要扩容
进入这个方法 :
集合和数组的对比:
1、长度:数组长度固定;集合长度可变
2、存储类型:数组可以存基本数据类型,也可以存引用数据类型;集合可以存引用数据类型【基本数据类型需要转换为包装类】