A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李挺 中级黑马   /  2013-2-2 18:56  /  1315 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 李挺 于 2013-2-3 09:32 编辑
  1. class Super
  2. {
  3.         int i=0;
  4.         public Super(String a)
  5.         {
  6.                 System.out.println("A");
  7.                 i=1;
  8.         }
  9.         public Super()
  10.         {
  11.                 System.out.println("B");
  12.                 i+=2;
  13.         }
  14. }


  15. class Demo extends Super
  16. {
  17.         public Demo(String a)
  18.         {
  19.                 System.out.println("C");
  20.                 i=5;
  21.         }
  22.         public static void main(String[] args)
  23.         {
  24.                 int i=4;
  25.                 Super d=new Demo("A");
  26.                 System.out.println(d.i);
  27.         }
  28. }
复制代码
这个打印的结果是
B C 5
我 翻开笔记发现毕老师写过这么一句话:在多态中成员变量的特点:无论编译和运行都参考左边。
那么应该打印的是
B C 2
为什么呢?

评分

参与人数 1技术分 +1 收起 理由
Rancho_Gump + 1

查看全部评分

6 个回复

倒序浏览
class Demo extends Super
{
        int i=3;//加上这个就是打印2了,没有的话说明子类没有i只有父类有,相当于你继承过来的。
                 //也就是说其实只有一个i,所以打印肯定是I的最后结果。
        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);
        }
}
回复 使用道具 举报
class Super
{
        int i=0;
        public Super(String a)
        {
                System.out.println("A");
                i=1;
        }
        
        public Super()   // 1
        {
                System.out.println("B");
                i+=2;  //i=2  在这里父类执行完毕,开始执行子类的
        }
}


class Demo extends Super
{
        public Demo(String a)  //2
        {
                super();//调用父类空的构造函数 1
                System.out.println("C");
                i=5;  //最后i=5  结果就是  B C 5
        }
        public static void main(String[] args)
        {
                int i=4;
                Super d=new Demo("A");
                System.out.println(d.i);
        }
}

回复 使用道具 举报
System.out.println(d.i);
为什么方法调用的是变量i是父类对象的。其实是多态的问题。多态是针对子类重写父类的方法的,但对变量则没有多态。
比如Super d=new Demo("A");是创建了一个子类对象并把它当成父类对象Super用也就是父类引用指向子类对象 此时,引用变量d有2个类型,编译时的类型为Super,运行时的类型为Demo.在代码编译过程中,Super 只能调用属于Super的方法. 不能调用Demo类里面的方法.注意,由于继承关系,如果Demo重写了Super的某个方法,
假如说Super有一个方法a(),而在代码编译过程中,Super.a()调用的是Super的a(),但在程序运行时,却运行的是Demo的a().
这就是多态
回复 使用道具 举报
在编译的时候编译器不管右边是什么类,只要左边的Super类能编译通过就行,不过运行的时候按照右边Demo类的实际情况来运行!!
回复 使用道具 举报
本帖最后由 罗广伟 于 2013-2-2 22:56 编辑

你在子类Demo方法中并没有定义i
public Demo(String a)
        {
                System.out.println("C");
                i=5;//这里的i是将继承父类的i值改为5
        }
所以你的打印结果5其实是子类改变父类i后的值
如果此处改为int i = 5;
运行结果就是B C 2 了
回复 使用道具 举报
本帖最后由 王昕 于 2013-2-3 00:47 编辑


构造函数执行的顺序:
Super d=new Demo("A");
这句调用了
public Demo(String a)
{
    super();    //这句是编译器自动给你补上的,这时打印B,i=2
    System.out.println("C");
    i=5;    //这时 i=5
}
那打印的当然是5。
实例变量能重新赋值,也就是说Super类有个 i ,他的所有子类的对象也一定都会有个 i ,能重新给这个 i  赋值。
你这个 i 本来就是Super的 i 被继承了又赋值了。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马