1.继承的概念&作用
在Java中,继承是面向对象编程的三大基本特性之一(还有封装和多态),允许一个类(子类/继承类)继承另一个类(父类/基类)的属性和方法
继承的核心目的是:
- 1.子类能够在不改变父类原有特性的基础上进行扩展
- 2.实现代码的复用和建立类之间的层次关系
在我们现有的知识储备基础上,如果要抽象出狗和猫,代码就要这么些:
但我们不难发现,在上述抽象狗和猫的过程中,有部分代码是重合的。这是因为狗和猫同属于动物,都有名字、毛色和年龄,都会睡觉。那么我可以定义一个Animal类来对这些相同的代码(共性)进行抽取,然后让Dog和Cat类来继承Animal类中的属性
2.继承的语法格式
要实现类之间的继承关系,需要借助extends关键字
修饰符 class 子类类名 extends 父类类名{
//其他代码
}
注意:
- 1.父类中的所有成员变量和方法都会被子类继承(即使是private修饰的成员也会被继承)
- 2.子类在继承父类原有是特性的基础上,必须要添加属于自己的特性(对父类做出扩展),否则没有继承的必要
3.如何访问父类中的成员
3.1 访问父类中的成员变量
3.1.1 当父类和子类不存在同名变量时
使用this关键字就能访问子类对象中的所有变量
3.1.2 当父类和子类存在同名变量时
注意:
- 1.当在子类对象内部访问成员变量时,优先访问自己的成员变量
- 2.如果自己没有,就从父类继承的成员变量中查找;如果父类中也没有,就报错
- 3.当父类和子类中存在同名变量时,优先访问子类自己的
如何访问父类中的同名变量?
下面讲到super关键字再说
3.2 访问父类中的成员方法
当访问父类和子类中的不同名方法时:
- 1.优先访问子类自己的方法
- 2.如果子类没有该方法,从父类中查找;如果父类也没有,报错
当访问父类和子类中的同名方法时:
- 3.如果父类和子类的同名方法构成重载,按照调用调用方法时传递的参数列表进行匹配
如果父类和子类的方法不仅方法名一样,参数列表也一样呢?
此时父类和子类的方法之间构成了重写。重写的方法也可以通过super关键字来访问。至于重写是什么?以及它们之间的调用关系等到讲多态的时候再介绍
4.super关键字
4.1 使用super访问父类的成员
在Java中,super关键字用于在子类中引用其父类的成员。以上面的dog对象为例,super的访问范围如下:
所以在父类和子类中出现同名成员变量时,如果想要访问父类的同名变量就需要借助super关键字
如果想要访问父类和子类中方法名一样,参数列表也一样的成员方法时,也可以借助super关键字
4.2 super&this的共性和区别①
共性:
- 1.都属于Java中的关键字
- 2.都只能在非静态方法中访问非静态的方法和变量
区别:
- 1.this表示当前对象的引用,当前对象就是调用实例方法的对象;super是指向 当前对象中 从父类继承的成员方法和变量 的引用
- 2.从访问范围来看,this可以访问当前对象中的多有成员,但是super只能访问当前对象中从父类继承的成员
5.构造方法&初始化顺序
5.1 父类和子类的构造关系和执行顺序
当创建一个子类对象时,Java会先调用父类的构造方法对父类的成员变量进行初始化,在父类初始化完毕后再调用子类的构造方法对子类的成员变量进行初始化(先有父再有子)。而在子类的构造方法中调用父类的构造方法也需要借助super关键字
即使调用父类的无参构造方法,在子类的构造方法中也必须要显式地写出super
- super语句必须放在构造方法中的第一行
5.2 super&this的区别②
- 1.在构造方法中,this(…)用于调用本类构造方法,super(…)用于调用父类构造方法。this(…)和super(…)都必须放在构造方法中的第一句,所以在构造方法中this(…)和super(…)不能同时存在
- 2.在子类构造方法中一定存在super(…)的调用(因为父类会默认生成无参构造方法),但是this(…)用户不写就没有
5.3 初始化顺序
在上篇JavaSE(7)——类和对象(二)中介绍了三种代码块的作用和执行顺序。
- 1.实例代码块一般用于初始化实例成员变量,静态代码块一般用于初始化静态成员变量
- 2.静态代码块最先执行且在整个类的声明周期中只会执行一次;实例代码块比构造方法先执行,每实例化一个对象都会执行实例代码块
当对象之间引入了继承关系时,父类和子类的代码块和构造方法的执行顺序是怎么的呢?
public class Father {//public Father(){System.out.println("父类的无参构造方法");}//{System.out.println("父类的实例代码块");}//static {System.out.println("父类的静态代码块");}
}
public class Son extends Father {//public Son(){super();System.out.println("子类的无参构造方法");}//{System.out.println("子类的实例代码块");}//static {System.out.println("子类的静态代码块");}
}
public class Test {//public static void main(String[] args) {Son son = new Son();}
}
执行结果:
父类的静态代码块
子类的静态代码块
父类的实例代码块
父类的无参构造方法
子类的实例代码块
子类的无参构造方法
6. 访问限定修饰符——protected(受保护的)
被声明为protected的成员变量/方法,可以被同一个包中的任意类访问,也可以被其他包中的子类访问
注意一:
protected成员的访问权限是基于类层级结构(继承)和包结构的,而不是对象的引用
要想访问父类的protected成员只能在子类内部,无法在外部包的非子类中通过子类的引用来访问
注意二:
在子类中,只能通过子类自己的引用来访问父类的protected成员
;无法在子类中通过其他子类的引用来访问父类的protected成员
6.final关键字
在Java中,final关键字主要用于限制类、方法和变量的可变性和可继承性
6.1 final修饰类
表示该类不能被继承
6.2 final修饰成员方法
表示该方法不能被重写
重写的概念下篇博文再介绍
6.3 final修饰变量
final修饰成员变量:定义成员变量的同时必须进行初始化
final修饰局部变量:
- 1.定义局部变量的同时进行初始化,之后无法修改该变量的值
-2.定义局部变量时未初始化,在第一次初始化之后,无法再修改该变量的值