class Father
{
int m=6;
public Father(){this.show();}
void show(){System.out.println("父");}
}
class Child1 extends Father
{
int m;
//Hint m=5;
void show(){System.out.println(m);}
}
public class test
{
public static void main(String args[])
{
Father n=new Child1();
}
}
为什么结果为0  ?Java

解决方案 »

  1.   

    怎么可能是0呢,按道理是new child1()时,由于父类里有构造函数他会使用父类的构造函数创建对象,此时m=6,
    然后由于子类实现了show()方法,应该调用子类的show()方法,应该输出6才对,LZ是不是弄错了?
      

  2.   

    1:Child1继承于Father故有了Father的一些特性
    2:在Child1中定义了与Father中一样的int m属性,Child1中的m会屏蔽了Father中的m属性,当然方法show也是一样的道理。
    3:在java中int类型如果不进行初始化会默认为0
    4:你在main函数中创建的实体类是Child1
    5:由于Chlid1没有实际构造方法,故在new时,调用父类的构造方法
    因此,会输出0
      

  3.   

    初始化顺序问题,参考一下:
    http://wenwen.soso.com/z/q191435823.htm
      

  4.   

    创建对象的三个步骤: 1.分配内存空间; 2.初始化属性; 调用构造方法;
    Father n=new Child1(); // new 创建了一个child1()对象,将其当作Father对象来看待;
    若父类方法被重写,静态方法会调用父类的;非静态方法会调用子类重写后的;
      

  5.   

    类的初始化(比如new),在类能够被初始化之前,它的直接超类,以及递归的,它的直接超类的直接超类(孩子他爷爷)必须被初始化。也就是child被初始化前,object、father类会被初始化(必须有了爷爷、爸爸、才会有孙子)
      

  6.   

    java的就近原则 m没有初始化  所以默认是0
      

  7.   

    方法可以重写,但是属性不会被重写。
    上面child1中重写了父类中的show()方法,所以将父类中的方法覆盖。
    但又因为属性不会被重写,所以方法回去调用child1中的属性m,结果楼主看到了,是0
      

  8.   


    说的不错,只有第5条错了。并不是“由于Child1没有实际构造方法”,“故”“调用父类的构造方法”一个类必定有构造方法,如果没有写,则有一个默认的、无参的构造方法。一个类不管有几个构造方法,其每一个构造方法的第一句必然调用本类的构造方法或父类的构造方法,如果没有写,则有一个默认的、隐藏的 super();,此时如果父类没有可见的无参构造方法,则子类不能通过编译。
      

  9.   

    继承情况下类的初始化顺序
    1.父类静态变量
    2.父类静态块
    3.子类静态变量
    4.子类静态块
    5.父类非静态变量
    6.父类非静态块
    7.父类构造函数
    8.子类非静态变量
    9.子类非静态块
    10.子类构造函数由于在父类构造函数(7)中调用子类覆盖的方法,但是此时子类非静态变量m(8)还没有被初始化,初值为0.
    所以输出0.
    如果将子类中的m改为static,结果就是5.
      

  10.   

    m 未被初始化  所以int默认初始化为0
      

  11.   


    说的不错,只有第5条错了。并不是“由于Child1没有实际构造方法”,“故”“调用父类的构造方法”一个类必定有构造方法,如果没有写,则有一个默认的、无参的构造方法。一个类不管有几个构造方法,其每一个构造方法的第一句必然调用本类的构造方法或父类的构造方法,如果没有写,则有一个默认的、隐藏的 super();,此时如果父类没有可见的无参构造方法,则子类不能通过编译。
      

  12.   

    重新启动tomcat