欢迎来到@一夜看尽长安花 博客,您的点赞和收藏是我持续发文的动力
对于文章中出现的任何错误请大家批评指出,一定及时修改。有任何想要讨论的问题可联系我:3329759426@qq.com 。发布文章的风格因专栏而异,均自成体系,不足之处请大家指正。
专栏:
文章概述:对 super_子类对象内存结构_继承树追溯的介绍
关键词:super 子类对象内存结构 继承树追溯
本文目录:
super关键字
- super“可以看做”是直接父类对象的引用。可通过super来访问父类中被子类覆盖的方法或属性。
- 使用super调用普通方法,语句没有位置限制,可以在子类中随便调用。
- 在一个类中,若是构造方法的第一行没有调用super(...)或者this(...); 那么Java默认都会调用super(),含义是调用父类的无参数构造方法。
【示例】super关键字的使用
public class TestSuper01 {
public static void main(String[ ] args) {
//创建实例并调用方法
new ChildClass().f();
}
}
class FatherClass {
public int value;
public void f(){
value = 100;
System.out.println ("FatherClass.value="+value);
}
}
class ChildClass extends FatherClass {
public int age;
public void f() {
super.f(); //调用父类的普通方法
value = 200;
System.out.println("ChildClass.value="+value);
System.out.println(value);
System.out.println(super.value); //调用父类的成员变量
}
public void f2() {
System.out.println(age);
}
}
在我上面的代码中,虽然子类 ChildClass
继承了父类 FatherClass
,但是 value
这个成员变量在子类中并没有重新定义。在Java中,如果子类没有重新定义父类的成员变量,则子类和父类中的成员变量实际上是同一个变量。因此,无论通过子类对象还是通过 super
关键字访问 value
,它们都指向的是同一个变量。
具体来说,子类和父类中的 value
都是实例变量,它们的访问权限是公共的(public
)。因此,子类可以直接访问父类的 value
,而 super.value
表示显式地访问父类中的 value
。
在 ChildClass
中,当我通过 super.value
访问 FatherClass
中的 value
时,因为这两个变量是同一个变量,所以它们的值是相同的。没有发生变量的重定义或者隐藏,所以 super.value
和 value
的值都是 200
,这是因为 f()
方法中对 value
进行了赋值操作。
如果希望在子类中重新定义 value
,可以在 ChildClass
中声明一个新的 value
变量,这样就会遮蔽父类中的 value
,从而使子类和父类中的 value
成为不同的变量。
如下例所示:
package basic_grammar;
public class TestSuper01 {
public static void main(String[ ] args) {
//创建实例并调用方法
new ChildClass().f();
}
}
class FatherClass {
public int value;
public void f(){
value = 100;
System.out.println ("FatherClass.value="+value);
}
}
class ChildClass extends FatherClass {
public int value;
public int age;
public void f() {
super.f(); //调用父类的普通方法
value = 200;
System.out.println("ChildClass.value="+value);
System.out.println(value);
System.out.println(super.value); //调用父类的成员变量
}
public void f2() {
System.out.println(age);
}
}
继承树追溯
属性/方法查找顺序:(比如:查找变量h)
- 查找当前类中有没有属性h
- 依次上溯每个父类,查看每个父类中是否有h,直到Object
- 如果没找到,则出现编译错误。
- 上面步骤,只要找到h变量,则这个过程终止。
构造方法调用顺序:
构造方法第一句总是:super(…)来调用父类对应的构造方法。所以,流程就是:先向上追溯到Object,然后再依次向下执行类的初始化块和构造方法,直到当前子类为止。
注:静态初始化块调用顺序,与构造方法调用顺序一样,不再重复。
【示例】继承条件下构造方法的执行过程
public class TestSuper02 {
public static void main(String[ ] args) {
System.out.println("开始创建一个ChildClass对象......");
new ChildClass();
}
}
class FatherClass {
//创建构造方法
public FatherClass() {
System.out.println("创建FatherClass");
}
}
class ChildClass extends FatherClass {
public ChildClass() {
System.out.println("创建ChildClass");
}
}
执行结果如图所示: