a=2;
s1的变量a与其他无关;并其他类初始化时对对象的内部变量无影响

解决方案 »

  1.   

    同意 vampire1129(Panther) 的看法 因为是s1=new SubClass(); 调用的应该是SubClass();
      

  2.   

    结果是8
    注意其中的一句是:
    SuperClass s1=new SubClass();
    如果它是
    SubClass s1=new SubClass();
    那结果当然是2,但是把子类实例化后赋值给超类:发生了如下变化:
    new SubClass()的确发生效用了,SubClass的构造也运行了,SubClass的a值为2,但是s1被声明为
    SuperClass,当有了此声明后,只要是SuperClass的对象就有了实例变量a=8,SubClass的a和SubClass的构造无法对SuperClass的a造成影响,SuperClass没有被new,也就没有构造,所以a的值还是8
      

  3.   

    本题是这样的,因为你的在构建器里调用了对象级的成员方法,而且此方法是公共的,这样是不允许的,会造成混乱,你可以把超类的add方法声明为private,结果就是9.好好看看构建器和多形性就明白了
      

  4.   

    kinzey34(无声之舞) :所以说superclass也调用了构造器,
      

  5.   

    ldxjava(爪哇国王):
    既然说superclass也调用了构造器,那为什么没有执行a=a+1?
      

  6.   

    调用了构造器,但执行的是subclass中的add(int i)。所以本身的a没有被修改。而这时的subclass还没有分配内存,所以也不会修改subclass中的a。
      

  7.   

    这个问题很简单阿
    因为声明的时候,s1是SuperClass,所以s1.a访问到的a是SuperClass中的a
    你试试看加一句:System.out.println(((SubTest)t1).a);  -- 结果就是2了
    SuperClass的构造函数肯定是被调用了的,无需质疑,
    但是调用的add(int)方法,在实际运行中,运行的是SubClass的方法,影响到的field也是
    SubClass里面的,对SuperClass中的a没有影响--也就是说,SubClass其实没有覆盖SuperClass中的a。如果你不相信我说的,可以找个Optimizeit Code Coverage验证一下
      

  8.   

    总结一下 SubClass中的add(int)覆盖了SuperClass中的方法add(int)
    但是SubClass中的a没有覆盖SuperClass中的a
    而打印出来的,是SuperClass中的a还望高人指点
      

  9.   

    当然是8呀,SuperClass s1=new SubClass(); 取得a=8 
    SubClass s2=new SubClass(); 取得a=2;
    这两个a实际是不同的,不会互相改变,只不过是名字相同的不同变量罢了!
      

  10.   

    同意 kinzey34(无声之舞) 的说法,高手啊:)
      

  11.   

    class SuperClass{
    int a=8;
    SuperClass(){
    //System.out.println(a);
    System.out.println("superclass!");
    add(1); }
    public void add(int i){
    System.out.println("superclass!add");
    a=a+i;
    System.out.println("super:"+a);
    }
    }class SubClass extends SuperClass{
    int a=0;
    SubClass(){
    System.out.println("subclass!");
    add(1);
    }
    public void add(int i){
    System.out.println("subclass!add");
    a=a+2*i;
    System.out.println("sub:"+a);
    }
    }public class Test{
    public static void main(String[] args){
    SuperClass s1=new SubClass();
    //SubClass s1=new SubClass();
    //SubClass s2=new SubClass();
    System.out.println(s1.a);
    }
    }
    ---------- Run Java Program ----------
    superclass!
    subclass!add
    sub:2
    subclass!
    subclass!add
    sub:2
    8Output completed (0 sec consumed) - Normal Termination
      

  12.   

    对于s1.a等于8,jigsaw(jigsaw)的说法是正确的。对于s2.a等于2,请看SubClass的等价代码:
    class SubClass extends SuperClass
    {
        int a;  //定义a,此时a等于0    SubClass()
        {
            super();
            a = 0;  //赋值,虽然定义的地方写了int a=0,实际上a=0这个操作在这里发生
            add(1);
        }    public void add(int i)
        {
            a = a + 2 * i;
        }
    }
      

  13.   

    public class Test{
    public static void main(String[] args){
    SuperClass s1=new SuperClass();
    System.out.println(s1.a);
    System.out.println();
    SubClass s2=new SubClass();
    System.out.println(s2.a);
    System.out.println();
    SuperClass s3=new SubClass();
    System.out.println(s3.a);
    }
    }---------- Run Java Program ----------superclass!
    superclass!add
    super:9
    9superclass!
    subclass!add
    sub:2
    subclass!
    subclass!add
    sub:2
    2superclass!
    subclass!add
    sub:2
    subclass!
    subclass!add
    sub:2
    8
      

  14.   

    run SuperClass()
    SuperClass.a=8
    begin SuperClass's add(1)
    a=0,run add a = a + 2 * i
    a=2,after run a = a + 2 * i
    after SuperClass's add(1),SuperClass.a=8
    run SuperClass() end.
    run SubClass()
    SubClass.a=0
    begin SubClass's add(1)
    a=0,run add a = a + 2 * i
    a=2,after run a = a + 2 * i
    after add,SubClass.a=2
    run SubClass() end.
    8
      

  15.   

    class base{
           int i = 100;
           public void print() {
                   System.out.println(i);
           }
    }
    class derived extends base{
           int i = 999;
           public void print() {
                   System.out.println(i);
           }
    }class test{
           public static void main(String[] args) {
                   base b = new base();               derived d = new derived();
                   b.print();
                   System.out.print(b.i);
                   d.print();
                   System.out.print(d.i);
                   base b2 = d;
                   b2.print();
                   System.out.print(b2.i);
           }
    }
    很简单的,前面的调用:
                   b.print();
    打印100
                   System.out.print(b.i);
    打印100
                   d.print();
    打印999
                   System.out.print(d.i);
    打印999.              b2.print();打印999这是因为java是在运行过程中采用了动态联编的方法,在运行时刻来决定该reference指向的什么类的对象,从而决定调用哪一个类的方法,而不是根据reference的类型来决定调用哪一个类的方法但是
                   System.out.print(b2.i);
    打印什么呢?结果是100, 而不是999。这是因为,在动态联编过程中,只是函数参与了,而对于类中的变量,则还是以静态的方式编译的,就是说,编译器是凭借reference的类型来决定类变量的。b2是base类型的reference, 所以b2.i
    是基类中的变量的值。
      

  16.   

    JAVA中的函数按C++的说法都是虚函数,
    虚函数操作的数据成员都是其真实对象的,
    因此SubClass的对象构造时自动调用SupperClass的构造函数,
    SupperClass的构造函数再调用add函数时调用的是SubClass的add函数,操作的对象也是
    SubClass的a,没有影响Supper.a,
    所以最后打印出来是 8.我用C++测试,打印出来是9,换句话说C++的SupperClass构造器调用的是自己的成员。
    可见JAVA的实现有缺陷。所以要避免这种容易出现问题的代码。
      

  17.   

    如果不是由构造器调用add,相信大家都可以得出正确结果。
    但由构造器调用add,就让人迷惑了。按理构造器当然初始化自己的成员,即使调用函数,
    也是调用自己的函数,否则初始化就不能达到要求的结果。但JAVA却不是这样。由此可以想到,如果SubClass的数据成员覆盖了SupperClass的数据成员,必然导致SupperClass相应的数据成员不能正确的初始化。这应该是JAVA的缺陷吧。如果一个类继承层数较多,难免会出现派生类定义和基类相同的数据成员,这时影响基类的
    工作,呵呵。。
      

  18.   

    哦!
    子类发放重载了父类方法。
    就象我们写的APPLET中PAINT方法。成员变量也重载了。多态的表现吧。学无止境啊!
      

  19.   

    SuperClass s1=new SubClass();
    我们可以把它看成
    SuperClass s1;
    SubClass s2=new SubClass();
    s1=s2;
    这是一个超类对子类的引用,在java的概念中有这样一段:使用超类引用来引用
    自类对象并激活draw方法,那程序将会正确地动态选择子类的draw方法,
    这种方法称为动态方法绑定(超类和子类都包含draw方法)。所以我不认为这是JAVA的缺陷
      

  20.   

    其实要正确调用父类的话,可以使用super的关键字,这样在一定程度上可以避免问题的出现。
      

  21.   

    结果有三种可能8 ,4,2。
    但是运行的结果是8。这跟java对象的结构有关。
    在new SubClass()时会按照类的继承体系从Object一直构造到SubClass。当构造到SuperClass时会根据多态原则调用SubClass.add,
    当构造到SubClass()时同样也会调用SubClass.add(),这样SubClass.add()就被调用了两次,这就是为什么a的值可能是4,但是绝对
    不可能是4,这跟java编译器的编译原理有关。
    class SubClass extends SuperClass{
    int a=0;
    SubClass(){
    add(1);
    }
    public void add(int i){
    a=a+2*i;
    }
    }
    被编译后的伪代码为:
    class SubClass extends SuperClass{
    int a;
    SubClass(){
    a = 0;
    add(1);
    }
    public void add(int i){
    a=a+2*i;
    }
    }
    即把对字段的赋值语句转移到构造器中的最上层,这样的话,当SuperClass类的构造器运行完后,因为调用SubClass.add()的缘故而使
    SubClass.a=2,在SubClass的构造器中将SubClass.a先清为0,接着调用SubClass.add(),这样SubClass.a=2。此时s1中有关于a的
    两个版本一个是a=8,另一个是a=2,当调用s1.a时取的是SuperClass.a,而不是SubClass.a,因为java只对Method多态,不会对Fied多态。
      

  22.   

    大家可以将楼主的代码修改为以下代码,运行看看结果
    class SuperClass{
    int a=8;
    SuperClass(){
    System.out.println("SuperClass()");
    add(1);
    }
    public void add(int i){
    System.out.println("SuperClass.add()");
    a=a+i;
    }
    }class SubClass extends SuperClass{
    int a=0;
    SubClass(){
    System.out.println("SubClass()");
    add(1);
    }
    public void add(int i){
    System.out.println("SubClass.add()");
    a=a+2*i;
    }
    }public class Test{
    public static void main(String[] args){
    SuperClass s1=new SubClass();
    System.out.println(s1.a);
    }
    }
      

  23.   

    如果在class SuperClass类前加上abstract声明的话本题就是对抽象超类引用的实例了。
      

  24.   

    同意cbhyk()
    改个值就知道了:
    class SuperClass{
    int a=8;
    SuperClass(){
    System.out.println("SuperCreate");
    add(1);
    }
    public void add(int i){
    System.out.println("Superadd:"+i);
    a=a+i;
    }
    }class SubClass extends SuperClass{
    int a=1;
    SubClass(){
    System.out.println("SubCreate");
    add(1);
    }
    public void add(int i){
    System.out.println("SubAdd:"+i);
    a=a+2*i;
    System.out.println("this.a="+a+",super.a="+super.a);
    }
    }public class Test{
    public static void main(String[] args){
    SuperClass s1=new SubClass();
    System.out.println(s1.a);
    }
    }
      

  25.   

    建议把SuperClass中的变量a改为b ,就很清晰的看出结果了
      

  26.   

    一看就知道没有好好的读think in java!
    仔细看看上塑造型,
    SuperClass s1=new SubClass();
    new SubClass()后a的值为2,因为调用了SubClass的构造方法
    但是上塑造型以后,a使用的是SuperClass中的值,并未调用构造方法,所以值为8SubClass s2=new SubClass();s2.a的值为2,因为调用了构造方法SuperClass s3=new SuperClass();s3.a的值为9,同上
      

  27.   

    knight_qmh(辉) 的例子很好.
    看来大家对重载和覆盖理解的还不够