java 继承 补充:子类能继承父类中的哪些内容?
继承内存图
父类中有:成员变量、构造方法、成员方法三部分内容。
非私有修饰符:private、...
私有修饰符:private
构造方法无论是否私有都不能继承;成员变量总是能继承(无论是否能使用);成员方法被非私有修饰符修饰时能继承,被私有修饰符修饰时不能继承。
构造方法的继承
构造方法不能继承。因为java中要求构造方法的名与类名一致,但继承的父类的构造方法名显然与子类的类名不同。
成员变量的继承
在方法区中加载字节码文件时,不仅要加载自身的字节码文件,还需要加载父类的字节码文件。在堆内存中,新建一个对象时,新开辟的空间分成两个部分,其一存储父类的成员变量,其二存储子类的成员变量。
但需要注意的是,被私有化修饰符private修饰的成员变量,虽然可以被继承,但无法被直接使用,而需要利用set/get使用。
成员方法的继承
从最顶级的父类开始,设立虚方发表,存储被非private、非static、非final修饰的方法,然后依次向后传递,依次添加虚方法,大大提升性能。虚方法表与方法重写之间关联很大。
只有虚方法表才能被子类继承。
继承的特点
成员变量的访问特点
就近原则。
先在局部位置查找,再到本类成员位置中查找,再到父类成员位置查找。如果出现成员变量重名的情况:若在成员方法中不加修饰,则会现在方法中查找,如果方法中没有则会到子类中查找,再没有才会到父类中查找;添加了this关键字以后,会跳过成员方法,不在方法中查找变量,而是直接先在子类成员变量中查找,子类中没有则会去父类中查找;添加了super关键字以后,会跳过成员方法和成员变量,直接在父类的成员变量中查找。
class Fu {
String name = "fu";
}
class Zi {
String name = "zi";
public void show() {
sout(name);
sout(this.name);
sout(super.name);
}
}
成员方法的访问特点
直接调用采用就近原则,利用super修饰则去父类中取用成员方法。
class Person {
public void eat() {
sout("person eat.");
}
}
方法的重写
父类的方法在子类中重新写一遍:当父类的方法不能满足子类现在的需求,需要进行方法的重写。表现为方法的声明与父类一致,使用@override(重写的注解:给虚拟机进行判读是否重写正确的标志)放在重写的方法上检校重写语法是否正确。
方法重写建议:重写的方法尽量和父类保持一致。
-
重写方法的名称、形参列表必须与父类一致
-
访问权限必须大于等于父类。(空着不写<protected<public)
-
只有被添加到虚方发表中的方法才能被重写
class Chinese() {
@override
public void eat() {
sout("chinese eat.");
}
}
构造方法的访问特点
父类中的构造方法不会被子类继承。
但子类中所有的构造方法都会默认先访问父类的无参构造,再执行自己。因为如果父类没有完成初始化,子类将无法使用父类中的数据。所以一定要先完成父类数据空间的初始化才会进行子类的初始化。