更奇怪的是,我稍微修改了上面的代码,把I设置为friendly int,如下:public abstract class A {
  int I=1;
  
  public void getI() {
    System.out.println("I="+I);
  }
}public class B extends A {
  int I=2;
  public static void main(String[] args) {
    B b=new B();
    b.getI();
  }
}那么,I已经不再是一个常量,B中的I已经覆写了A中的I,但为什么我调用b.getI()的时候,打印出来的依然是1呢? 百思不得其解。

解决方案 »

  1.   

    如果你想实现这个功能,就不应该把变量写成static的static属于类成员,而看你的意思是说每个子类都应该有一个自己的I变量,所以要不你就把变量改成非static的,而子类中不再声明变量I,这样每个对象都会从A那得到一个自己的I,但这有点违背你的初衷。还有一个办法就是你把A类的getI变成抽象函数,然后在每个子类中一一实现。个人拙见
      

  2.   

    大家有没有看我第二贴,我已经把变量改为non-static,这个应该属于基础问题,怎么没人能回答呢?
      

  3.   

    你的getI()方法没有在B类中重写,因此他执行的功能仍是在A类中的功能,所以输出的是1。
    建议你把getI()方法重写一次。
      

  4.   

    你那俩个例子能正确编译通过??
    我编译没通过。。  一个文件中好像不可以有两个public class吧?
      

  5.   

    有方法了,不过我还解释不通:
    public abstract class A {
      int I=1;
      
      public void getI() {
        System.out.println("I="+I);
      }
    }public class B extends A {
      {
        I=2;
       }
      public static void main(String[] args) {
        B b=new B();
        b.getI();
      }
    }
    可以使I=2
      

  6.   

    还有:
    public abstract class A {
      static final int I=1;//去掉private
      
      public void getI() {
        System.out.println("I="+I);
      }
    }public class B extends A {
      {I=2;}
      public static void main(String[] args) {
        B b=new B();
        b.getI();
      }
    }
    这样也是可以的。
      

  7.   

    是啊,你的方法确实可以让I=2,但加了{}有什么不同呢?为什么加了就可以呢?不明白。按照Java的继承思想,当B继承了A以后,自然继承了A中的所有非private方法,那么B调用getI()应该返回B中的I,如果每次都要覆写getI()方法,那么,请问继承还有什么意义呢?
      

  8.   

    加了{}
    形成初始化块,它将在MAIN前就执行了,于是I=2;
      

  9.   

    其实继承的其中一个重要用途就是让子类共享父类的代码。但如果父类的某个方法需要调用自身的数据成员,而Java规范建议把数据成员定义为私有,那么子类继承了父类的方法,但调用方法的时候,该方法只能调用父类本身的数据成员,那么继承的作用实在让我相当失望。请问如何解决?
      

  10.   

    个人见解:有什么不对的请帮忙指出。继承中的规范,子类继承了父类的所有方法和字段,包括私有的和公有的,继承的东西不能去除。其中方法可以覆盖,但是对于私有字段是否能被覆盖,我就不知道了,core java中没有说明。我认为只能通过方法对其默认值进行改动。我的方法中,I不是私有的,所以可以对其进行覆盖,即改变它的默认值。你的代码中子类没有构造函数,由于继承了父类只能先调用父类构造函数——父类的默认构造函数。所以此时,I=1,造成子类的I=1,而不在初始化块中的I=2;我认为没被执行或是作为了一个局部变量I执行了赋值语句,所以没改动子类中的字段I的值。而用了初始化块,I就被认为是子类中的字段I,茄子类的初始化块中的指令后于父类的构造器执行,这就改变了I的值使它等于2