java中关键字 super表示的真正对象

 java中关键字 super表示的真正对象
    java中的super,大家都知道是表示一个父类的引用。上次群里见到一个网友询问 super.getClass().getName()的输出问题,大部分都知道输出的是当前这个类的类名。而不是父类的名称。关于这个问题的解释很多,基本都是说getClass()是一个final方法,说这个方法都是调用超父类Object的方法。这个解释很好,也容易理解,不过,我们从super这个关键词的本质入手,就能更清楚,为什么super.getClass().getName()会输出当前类的名称了。

先定义两个类,一个父类,一个继承的子类。

父类:

public class Parent {
	public String name;
	private int code;
	public Parent parent;
	//定义几个父类成员属性,parent将指向this父类对象
	public Parent()
	{
		//parent指向this,就是当前实例的父类对象,并输出hashcode和给code属性赋值
		parent=this;
		code=1001;
		System.out.println("Parent's code is:"+code);
		System.out.println("Parent hashcode is:"+this.hashCode());
	}
	//定义一个重载的构造方法,用于测试使用了哪个父类构造方法
	public Parent(String name){
		parent=this;
		this.name=name;
		System.out.println("Parent's name is"+name);
		code=1002;
		System.out.println("Parent's code is"+code);

		System.out.println("Parent hashcode is:"+this.hashCode());
	}
	public int getCode()
	{
		//打印父类code属性值,
		System.out.println("Parent :print code :"+code);
		return code;
	}
}

子类:

public class Child extends Parent{
	public String childName;
	private int childCode;
	//定义两个类的不同修饰符的属性
	public Child(String childName)
	{
		//给属性赋值
		this.childName=childName;
		//输出属性值,和类的hashcode值
		System.out.println("child's childName is:"+childName);
		System.out.println("child hashcode is:"+this.hashCode());
	}
	//测试方法
	public void test()
	{
		//通过super获取父类中的parent,这个成员就表示了父类对象。
		Child testChild=(Child)super.parent;
		//强转parent为子类类型。并输出子类中定义的属性,和获取父类getCode()方法
		System.out.println("testChild name is:"+testChild.childName);
		testChild.getCode();
	}
	public static void main(String[] args) {
		//实例化
		Child c=new Child("window");
		c.test();
	}
}

 

运行输出结果:

Parent's code is:1001

//首先输出这句,可以表示,父类默认的构造方法执行了。
Parent hashcode is:11985823

//这里输出的父类this对象的hashcode码


child's childName is:window

    //调用子类的构造方法,输出childName和hashcode码值,大家可以看到,父类的this对象和子类实例的对象,hashcode码是相同的。
child hashcode is:11985823

    //这里执行test()方法的结果。

    //使用Child testChild=(Child)super.parent 强制转换父类中指向父类this对象的parent对象为子类Child对象,并输出子类childName属性值。
testChild name is:window

    //输出结果上可以看出,这个parent其实就是子类的实例对象。应该说内存中的对象是同一个,只是不同的表示方式。

    //执行testChild.getCode(); 调用父类的getCode()方法,输出的和父类构造方法中的code值是相同的。
Parent :print code :1001

 

从上面可以看出super这个关键字所表示的引用父类对象,其实和当前实例化的子类对象在内存中是同一个对象,虽然不知道sun 的虚拟机是如何实现这个关键字的,但是这个super的等同效果就是(Parent)this,这里的this是当前代表当前实例化的子类对象。

通过在父类中添加一个Parent类型的成员,来指向父类实例化的那个this对象,达到引用父类对象的目的,使用super.parent来获得父类parent对象的引用。

运行的结果表明,这个parent应用的其实就是当前子类实例对象,通过强制转换为子类类型,这个父类Parent类型的parent也可以读取成员childName属性值。就表明了他们在内存中是同一个对象。而且他们的hashcode值也是相同的。

java说明中指出,super是代表父类对象的引用,而super()表示应用父类的默认构造方法,看起来这个super和c中的define有点相同作用的效果。在这个例子中,super代表的父类对象的引用,和父类中parent代表的都是父类对象的引用,parent其实就是当前内存中子类对象的引用,如同(Parent)this一样,这样就可以解释为什么使用(Child)super.parent可以得到子类成员childName。

回到开始的问题,super.getClass().getName(),这样,就很容易解释他为什么是输出当前类的名称了,因为构造一个实例化对象,其中,在父类和子类构造方法中,引用的对象都是同一个,都是当前实例化的子类对象。super关键字应该充当了一个类型转化的作用。

熟悉c的知道,c中经常使用强制转换指针类型来引用一些结构或变量的部分数据,如通过强制转换为不同结构类型,来引用不同数据大小的结构体。这里的应用效果应该等同,通过(Parent)Child可以通过转换为父类类型而只引用父类类型的那一部分数据。

 

javanew一个对象,和cc++这些和内存打交道的语言一样,都是会分配内存,在c中可能更直观一点,我们在此不讨论到底是分配了多大的内存问题。

new一个子类的时候,上面例子看到,父类的成员同样也有赋值初始化,说明,同样在内存中也有保存父类的信息空间,(Object类的不讨论)。

一个抽象点的图:



可能图表达不对,大概就是这个意思、
  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值