一.继承
1.继承的概念
在面向对象编程中,可以通过扩展一个已有的类,并继承该类的属性和行为,来创建一个新的类,这种方式成为继承。
tips:在Java语言中只有单继承。
2.继承在内存中的实现
代码:创建父类
public class Father(){
public Father(){
System.out.println("父类构造器");
}
}
创建子类:
public class Son(){
public Son(){
//super();隐式调用super()
System.out.println("子类构造器");
}
}
创建一个子类对象:
Son son = new Son();
这段代码在内存中产生的影响:
1.首先调用父类的无参构造方法,递归调用父类的父类的构造方法,直到调用到Object类的构造方法。
2.为Object类中的属性划分空间
3.为Father类中的属性划分空间,并叠加到为Object划分的空间后面。
4.为Son类中的属性划分空间,并叠加到为Father划分的空间后面。
执行结果:
父类构造器
子类构造器
3.重写与重载
比较 | 重写 | 重载 |
---|---|---|
发生的位置 | 子类中 | 本类中 |
访问修饰符 | 必须大于或等于父类的访问修饰符 | 不做要求 |
返回类型 | 必须相同 | 不作要求 |
方法名 | 必须相同 | 必须相同 |
参数列表 | 必须相同 | 必须不同 |
异常 | 不能抛出比父类更多的异常 | 不作要求 |
4.super与this
super. 和 this.
比较 | super | this |
---|---|---|
书写的位置 | 子类的方法中 | 本类的方法中 |
作用 | 访问父类的属性或方法 | 访问本类的属性或方法 |
super()和this()
比较 | super() | this() |
---|---|---|
书写的位置 | 子类的构造方法中 | 本类的构造方法中 |
作用 | 调用父类的构造方法 | 调用本类中其他的构造方法 |
tips:this()和super()都必须在构造器中的第一行,且二者只能选其一,如果子类的构造方法没有显示调用this()或者super()那么会隐式调用super()。
5.final、finally、finalize
final | 类 | 属性 | 方法 |
---|---|---|---|
特性 | 不能被继承 | 初始化后不能被重新赋值 | 不能被重写 |
finally
通常和try-catch语句配合使用,表示是否有异常发生,最后都必须执行的语句。
如:
try{
statement;
}catch(Exception e){
statement;
}finally{
statement;
}
finalize()
Object的一个方法,垃圾回收机制通过算法计算哪个对象应该被销毁,然后调用finalize()方法将其销毁。
二.类的高级概念
1.四种访问修饰符及其访问范围
访问修饰符 | 本类 | 本包中的子类 | 本包中的其他类 | 其他包中的子类 | 其他包中的类 |
---|---|---|---|---|---|
private | ✔ | ||||
默认 | ✔ | ✔ | ✔ | ||
protected | ✔ | ✔ | ✔ | ✔ | |
public | ✔ | ✔ | ✔ | ✔ |
2.封装
1.信息隐藏
将属性的访问修饰符设置为private,并提供public的getter/setter方法。
这样做增加了操作数据的灵活性,可以做只读或只写操作。并且可以在setter方法里面对数据有效性进行验证。
2.隐藏实现
隐藏内部实现,给外部提供一个接口。当修改内部实现时,不会影响到外部使用者。外部使用者不必关心内部实现。
3.static关键字
静态对象和非静态对象的区别
对比 | 静态对象 | 非静态对象 |
---|---|---|
拥有属性: | 是类共同拥有的 | 是类各对象独立拥有的 |
内存分配: | 内存空间上是固定的 | 空间在各个附属类里面分配 |
分配顺序: | 先分配静态对象的空间 | 继而再对非静态对象分配空间,也就是初始化顺序是先静态再非静态. |
static修饰符的作用
static | 属性 | 方法 | 初始化块 |
---|---|---|---|
作用 | 可以通过类名加点访问 | 可以通过类名加点访问 | 在类加载期执行一次 |
三.多态
1.多态的概念
2.静态多态
重载,和单独的重写(即用子类对象的引用调用子类中重写的方法)。是指在编译器就可以确定该执行的方法。
3.动态多态(重写+动态绑定)
1.重写
在子类中重新实现从父类继承来的方法
2.转型技术
具有继承关系的引用数据类型可以相互转换。但是将父类型转换为子类型会有一定的风险,不建议这样做。
3.instance
用法:
引用a instanceof 类XXX
在程序执行过程中判断引用a是否指向类XXX的对象。
4.动态绑定
在程序执行的过程中,根据具体对象的类型进行绑定。通过动态绑定,JVM必须沿着继承树向下找,判断一个方法是否被重写,如果方法被重写了,在运行时就执行子类的方法,否则执行父类的方法。
5.应用场景
1.多态参数:引用类型的参数可以传入任意该类型子类的实例。
2.异构集合:类型不同但是有相同父类的子类的数据集合。
四.抽象类和接口
abstract | 类 | 方法 |
---|---|---|
修饰 | 定义为抽象类 | 定义为抽象方法 |
作用 | 被继承 | 被实现 |
tips:继承了抽象类的类必须实现抽象类中的所有方法,除非是抽象类。
区别 | 抽象类 | 接口 |
---|---|---|
实现关键字 | abstract | interface |
属性 | 和普通类相同 | 全部是静态常量 |
方法 | 抽象类中可以没有抽象方法 | 全部是抽象方法 |
作用 | 被继承 | 被实现(实现了接口就必须实现接口中所有的方法)除非是抽象类 |
实现 | 一个类智能继承一个抽象类 | 一个类可以实现多个接口 |
应用场景 | 与生俱来的类写在抽象类中,比如“门”必须能“开”和“关” | 后天可以附加的行为比如“按门铃” |