一个子类型的对象转型成父类,以及再次转回子类的过程中,对象的成员变量是如何变化的?
首先,验证代码如下:
<span style="font-family:Microsoft YaHei;font-size:12px;"></span><p> class A
</p><p>{
int x = 1;
}
class B extends A
{
int x = 2;
int y = 3;
}
class Test
{
public static void main(String[] args)
{
B a = new B();
a.x++;
a.y++;
System.out.println(a.x+" "+a.y); //输出3 4,这没啥说的。</p><p>
A b = a;
System.out.println(b.x++);//这里输出了1,证明有了一个新的x,注意这里的“++”操作
</p><span style="font-family:Microsoft YaHei;font-size:12px;"> B c = (B)b;
System.out.println(c.x+" "+c.y);//证明最开始a对象里的x,y值并没有因为转型而消失
A d = c;
System.out.println(d.x);//输出了2,证明无论是向上转型还是向下转型都不会造成成员变量“丢失”。</span><pre name="code" class="java"><span style="font-family:Microsoft YaHei;font-size:12px;"> }</span>
<span style="font-family:Microsoft YaHei;font-size:12px;">}</span>
于是,成员变量传递的过程就很明显了,A b = a ; 这条代码,并不是改变了原本对象的x值,而是新增了一个x值,换句话说,这条代码就是给对象新开辟了一部分空间,专门放新加入进来的A类定义的成员变量,各存各的。
而考虑到后面的B c = (B)b ; 及其之后的运行结果,这里我暂且用这样一种说法:
一个对象不只能存它的声明类所定义的成员变量,还可以存储这个类所有超类定义的成员变量,后者会在对象转型时生效,而这些成员变量互不影响。
eg.拿学生和人做个例子
人出生年龄0岁,学生上小学年龄6岁,一个学生对象a,他的年龄变量初始化为6,并一年年学业,长到了9岁,这时把这个学生向上转型成一个普通的人,就有了新的年龄属性,初始化为0,如果有必要,这个年龄可以再设成9,就算没有必要,如果之后他又被转型回学生,他的年龄也还是9。
换句话说,对象的属性不一定都是真实有效的,尤其是转型之后的新的成员变量,但就有的成员变量并没有丢失,所以对实际运行影响不大。