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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© jagon 中级黑马   /  2014-3-17 10:34  /  1373 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 jagon 于 2014-3-17 23:12 编辑

package test1;
abstract class A{
        public A(){
                this.print();
        }
        
        public abstract void print();
}

class B extends A {

        private int data=10;
        public B(int data) {
                this.data=data;
        }

        public void print(){
                System.out.println(data);
        }
}

public class demo1{
        public static void main(String[] args) {
                new B(100);
        }

        
}
为什么输出结果是0,不是应该是100吗?请帮忙解答,谢谢了!

8 个回复

倒序浏览
子类构造函数 第一行 有个默认的super();
父类在初始化的时候没有初始化到data,所以默认初始化是0

你写 new B(100).print(); 就可以看到100了  !!!
回复 使用道具 举报
执行的顺序是这样的:1.B中的data先初始化为0  2.再执行B的构造方法(注意B的构造方法省略super()),因此打印的是0
具体参考:http://blog.csdn.net/macheng365/article/details/6403050
回复 使用道具 举报
虽然回答你问题,但是我也学到不少,构造函数有个父类的super()是空参数的,调用的print是父类的,父类的print里面什么都没有,所以打印出0
回复 使用道具 举报
你的子类里面并没有调用过print()方法,并且子类在初始化时,调用构造函数,默认先加载父类的构造函数。
这样就行了。亲
  1. package test1;
  2. abstract class A{
  3.         public A(){
  4.                 this.print();
  5.         }
  6.         
  7.         public abstract void print();
  8. }

  9. class B extends A {

  10.         private int data=10;
  11.         public B(int data) {
  12.                 this.data=data;
  13.                 print();
  14.         }

  15.         public void print(){
  16.                 System.out.println(data);
  17.         }
  18. }

  19. public class demo1{
  20.         public static void main(String[] args) {
  21.                 new B(100);
  22.         }

  23.         
  24. }
复制代码
回复 使用道具 举报 1 0
new B(100) 调用b的构造函数,b的构造函数中有super()调用a的构造函数
过程中虽然传递了100但是没有调用b的print()所以没有输出100
回复 使用道具 举报
本帖最后由 刘一博 于 2014-3-17 22:25 编辑

main方法中new B(100);
首先调用B的带参构造器
  1. public B(int data) {
  2.                 super(); //当子类初始化时,默认调用父类无参构造器,代码中可省略,但默认调用这一方法
复制代码
父类无参构造函数中调用了print方法,由于子类重写了该方法,实际调用了子类的print方法,此时需注意类加载的顺序,构造函数在非静态成员变量的前面,则此时data还为0,则打印0
当赋值后再次调用print方法,此时输出100
输出结果为0,100
回复 使用道具 举报 0 1
abstract class A {
       
        public A() {
                this.print();
        }

        public abstract void print();
}

class B extends A {

        public int data = 10;

        public B(int data) {
                super();
                print();
                this.data = data;
        }

        public void print() {
                System.out.println(this.data);
        }
}

public class Demo_1 {
        public static void main(String[] args) {
                new B(100);
        }

}

/*
结果是:
0
10
*/
执行的过程:
1.data隐式初始化,即data = 0
2.执行B的构造函数第一条语句super(),此时data等于0,即输出0
3.data显式初始化,即data = 10
4.在执行B的构造函数中其它的语句,即输出10.



回复 使用道具 举报
  1. abstract class A{
  2.     public A(){
  3.             this.print();
  4.     }
  5.     public abstract void print();
  6. }

  7. class B extends A {
  8.     private int data=10;    /*如果改为private static int data=10;可以明显清楚是在执行this.data = data;前执行super();时data值初始化值0,而定义为static随类加载而加载也就初始化值为10;*/
  9.     public B(int data) {
  10.             //super();       出现0,因为此处先初始化父类构造函数,执行时下面赋值语句未执行。
  11.             this.data=data;
  12.     }

  13.         public void print(){
  14.             System.out.println(data+"  hehe");
  15.     }
  16. }

  17. public class demo1{
  18.     public static void main(String[] args) {
  19.             new B(100);
  20.     }   
  21. }
复制代码

LS们基本都说到点上了,LZ理解后可以自行想合适的方式修改。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马