标题: 多态 [打印本页] 作者: 黄昆 时间: 2012-7-13 09:51 标题: 多态 第一题:
class A{
int num=2;
}
public class B extends A{
int num=3;
public static void main(String[] args) {
A a=new B();
System.out.println(a.num );
}
}
运行结果是:2
第二题:
class Super
{
int i=0;
public Super(String a)
{
System.out.println("A");
i=1;
}
public Super()
{
System.out.println("B");
i+=2;
}
}
class Demo extends Super
{
public Demo(String a)
{
System.out.println("C");
i=5;
}
public static void main(String[] args)
{
int i=4;
Super d=new Demo("A");
System.out.println(d.i);
}
}
运行结果是:B C 5
问题:为什么第二题的运行结果不是:B C 0 呢?在多态中成员变量的特点:无论编译还是运行都是参考引用型变量所属的类。
这两道题是不是矛盾呀?有点不理解。求解! 作者: 陆强强 时间: 2012-7-13 10:01
Super d=new Demo("A");先public Demo(String a)初始化,因为super()隐式语句的存在,调用父类的 public Super()打印“b”,再给I赋值2
然后再打印“C”,最后给I赋值5,
System.out.println(d.i);这里的I继承了super后的I,不是主函数的I 作者: 黄昆 时间: 2012-7-13 10:10
class Super
{
int i=0;
public Super(String a)
{
System.out.println("A");
i=1;
}
public Super()
{
System.out.println("B");
i+=2;
}
}
class Demo extends Super
{
public Demo(String a) //2、父类初始化完,就开始调用子类的构造函数,因为没有定义i ,所以引用了父类的变量 i
{
System.out.println("C");
i=5; //3、给这个变量重新定义了一个值,
}
public static void main(String[] args)
{
int i=4;
Super d=new Demo("A"); //1、这里对象实例化的时候先是隐式的一个super();调用父类的构造函数。
System.out.println(d.i); //4、这里实际上是子类的变量引用复写了父类的变量,所以结果是5
}
} 作者: 黄丽慧 时间: 2012-7-13 10:28
楼主这两个题目,并不互相矛盾的,跟语句先后的执行顺序有关系,很细微的差别就会引起结果的差异:
class A{
int num=2;
}
public class B extends A{
int num=3;//你这里的num定义在实例化之前
public static void main(String[] args) {
A a=new B();//这里一创建实例,调用隐式的super(),前面的那个num就被重新赋值成2了,所以下面打印出来的结果是2
System.out.println(a.num );
}
}
class Super
{
int i=0;
public Super(String a)
{
System.out.println("A");
i=1;
}
public Super()
{
System.out.println("B");
i+=2;
}
}
class Demo extends Super
{
public Demo(String a)
{
System.out.println("C");
i=5;
}
public static void main(String[] args)
{
int i=4;
Super d=new Demo("A");//这里一创建实例,调用public Demo(String a)这个构造方法,先执行super(),所以打印B,i=2,紧接着打印C,又对i进行赋值,i=5.因此d.i的结果就是5了
System.out.println(d.i);
}
}作者: 黄昆 时间: 2012-7-13 10:34
明白了 作者: 陆鹏 时间: 2012-7-13 10:42 本帖最后由 陆鹏 于 2012-7-13 10:44 编辑
楼主请认真看程序执行顺序和红字部分。
package cn.heima;
class Super
{
int i=0;
public Super(String a)
{
System.out.println("A");
i=1;
}
public Super()//5---->跳到6
{
System.out.println("B");//6---->打印"B"
i+=2;//7.此时i=2了
}
}
class Demo extends Super
{
public Demo(String a)//3---->跳到4
{
//默认有一个super();4----->跳到5.
System.out.println("C");//9--->打印C
i=5;//10---->将5赋给i
}
public static void main(String[] args)
{
int i=4;//1---->这个i是在栈内存中,而后面的i是堆内存中的,所以这个i没有被用
Super d=new Demo("A");//2----->跳到序号3
System.out.println(d.i);//8--->跳到9
//11---->将堆内存中的i打印出来,此时i已经变为5了。
}
} 作者: 黄昆 时间: 2012-7-13 12:14
黄丽慧 发表于 2012-7-13 10:28
楼主这两个题目,并不互相矛盾的,跟语句先后的执行顺序有关系,很细微的差别就会引起结果的差异:
class A ...
恩,同感呀,感觉分数好难得呀!作者: 文密 时间: 2012-7-13 17:42
class A{
int num=2;
}
public class B extends A{
int num=3;
public static void main(String[] args) {
A a=new B();
System.out.println(a.num );
}
}
其实第一题很好理解:
记住这句话就行了
在多态中成员变量有特点:
无论编译和运行,都参考左边(引用型变量所属的类)。
第二题:
class Super
{
int i=0;
public Super(String a)
{
System.out.println("A");
i=1;
}
public Super()
{
System.out.println("B"); //4:打印"B"
i+=2; //5: i赋值为2;
}
}
class Demo extends Super
{
public Demo(String a)
{
//3 通过//super();隐示 调用父类有空构造函数
System.out.println("C"); //6 :打印出“c”
i=5; //7把I赋值为5
}
public static void main(String[] args)
{
int i=4; //1此变量在栈内存里面,没有在堆内存
Super d=new Demo("A");//2父类的引用指向了自己的子类对象 System.out.println(d.i); 所以//d.i=5
}
所以最后显示的是BC5;