super关键字
一.super关键字作用
1:主要存在于子类方法中,用于指向子类对象中父类对象。
2:访问父类的属性
3:访问父类的函数
4:访问父类的构造函数
下面看一个例子:
class FatherClass { public int value; public void f(){ value = 100; System.out.println ("FatherClass.value="+value); } } class ChildClass extends FatherClass { public int value; public void f() { super.f(); value = 200; System.out.println ("ChildClass.value="+value); System.out.println(value); System.out.println(super.value); } } public class TestInherit { public static void main(String[] args) { ChildClass cc = new ChildClass(); cc.f(); } }
结合上面程序在内存中的分布图如下:
首先从函数的入口进行分析
ChildClass cc = new ChildClass();
程序执行到这里时,首先在栈空间里面会产生一个变量cc,cc里面的值是什么这不好说,总而言之,通过这个值我们可以找到new出来的ChlidClass对象。由于子类ChlidClass是从父类FatherClass继承下来的,所以当我们new一个子类对象的时候,这个子类对象里面会包含有一个父类对象,而这个父类对象拥有他自身的属性value。这个value成员变量在FatherClass类里面声明的时候并没有对他进行初始化,所以系统默认给它初始化为0,成员变量(在类里面声明)在声明时可以不给它初始化,编译器会自动给这个成员变量初始化,但局部变量(在方法里面声明)在声明时一定要给它初始化,因为编译器不会自动给局部变量初始化,任何变量在使用之前必须对它进行初始化。
子类在继承父类value属性的同时,自己也单独定义了一个value属性,所以当我们new出一个子类对象的时候,这个对象会有两个value属性,一个是从父类继承下来的value,另一个是自己的value。在子类里定义的成员变量value在声明时也没有给它初始化,所以编译器默认给它初始化为0。因此,执行完第一句话以后,系统内存的布局如下图所示:
接下来执行第二句话:
cc.f();
当new出来一个对象的时候,这个对象会产生一个this的引用,而这个this的引用是指向自身,如果new 出来的对象是一个子类的对象的话,那么这个子类的对象里面会有一个super 去指向父类对象,因此,在这句话中产生了一个this,this指向自身,自身有一个super指向父类对象
在这个程序中子类的ChildClass方法重写了f()方法,之后又继承了父类的f()方法,此时的vaule是100,打印出 FatherClass.value=100 程序回到子类ChildClass中,此时的value值变成了200,打印ChildClass.value=200,当然后面打印的value值是子类的也就是200,而super.value是父类的value值也就是100,内存分布图如下所示: