public class TestAnimals {
public static void main (String [] args) {
Horse b = new Horse();
System.out.println(b.getI());
}
}class Animal {
private int i=1;
public int getI(){
return i;
}
public void setI(int i){
this.i=i;
}
}class Horse extends Animal {
int i=2;
}
--------------------------------------
执行TestAnimals 时,问什么结果是1   而不是2呢,

解决方案 »

  1.   

    把Animal 类的成员变量i  改为public,就可以输出2
    ----------------------
    请大家解释!
      

  2.   

    Animal中的i是私有的没有被继承所以在Horse中i与调用的方法没有任何关系
      

  3.   

    3楼的回答的正确,类中的私有变量是不能被继承的。要想能够继承就要改为Public
      

  4.   

    i在父类中是私有成员。你子类中声明的i和父类就没关系。要改变父类中i的值只能用seti()
    你先别做JAVA开发了,先来和我一起学基础如何,呵呵:)
      

  5.   

    把Animal 类的成员变量i  改为public,就可以输出2
      

  6.   

    这是一个很典型的继承问题。楼主说的有一个地方不对,在父类animal中,不管i是public还是private,TestAnimals 中输出的结果始终是1。
    我个人理解为:horse继承了animal,但 int i= 2是不同于父类中的i,也就是说,虽然和父类中成员变量i的名称一样,但子类中不是真正对父类中的i赋值。
      

  7.   

    既然:类中的私有变量是不能被继承的,
    那么:b.getI()更因该返回2,谁能把内存中的分配情况说一下另外:把Animal 类的成员变量i  改为public,就可以输出2,  这句话是对的,
      

  8.   

    不应该是public 应该用private 私有的不能访问超类!
    这是给继承的经典问题 也是最容易出错的地方
      

  9.   

    把Animal 类的成员变量i  改为public,就可以输出2,  这句话是不对
    ----------------------
    在子类中追加方法
    public int getI(){
    return i;
    }
    才可以返回2
      

  10.   

    同意 vagrant_xyz()  ,Horse中又没有getI(),怎么用的,楼主看错了把
    两个i各自在栈中分配,和public没什么关系
      

  11.   

    把Animal 类的成员变量i 改为public,就可以输出2这的确是不对的
      

  12.   

    晕,这好象是个很基础的问题啊,私有成员在继承类里是无法访问的.C++中protected和public属性的才可以被子类访问......
      

  13.   

    楼上的……父类中私有成员不能够被继承?!父类中私有的成员同样能够被继承,只不过不能够被访问罢了。子类不能够继承的父类成员是构造函数,除了构造函数之外的所有成员,不论是private、public、protected都能够被继承,只不过根据访问修饰不一样,访问的权限不同罢了。还有楼主的:“把Animal 类的成员变量i 改为public,就可以输出2”。这个……是不是楼主看错了?我的编译器运行了2次都没有发生楼主所说的现象呢。^_^public int getI(){
    return i;  //返回的i始终是Animal类中的属性i的值
    }楼主可以单步调试一下。
      

  14.   

    好像在c++中,不管是public还是private都是输出1
      

  15.   

    我的一点观点如下:
      1.子类可以继承父类的任何变量和方法,这肯定是。private、protected只是访问权限而已。
      2.java中的对象化过程应该是这样的:首先,jvm中应首先载入class对象【这儿不是实例化对象】,它作为生成实例对象的模板;这个模板中有变量、方法;其中方法、静态变量只有一份,也就是说,从此模板生成的对象中,不会再含有方法、与静态变量;生成的任何对象共享class对象的静态变量和方法。 根据你的例子来说,父类class对象中有i变量、set get两个方法。子类class中应有i【继承于父class对象】、i【子class对象】两个变量、set get两个方法【继承于父class对象】。 对于实例变量来说,每生成一个对象,都会在内存中产生新的存储空间,用于存放实例变量的值;对于上例来说,就是每次生成对象时,都会为两个i分配空间。上面我们说方法只有class对象中的一份,那么在对特定对象调用方法时,方法就会使用本对象的相关实例变量。那么方法如何和相关变量相关?它只能在类的定义中建立联系。对上例来说,set get方法只能和父类中的i相关,这在类定义时,就规定好了。在上例中,如果在父类中定义一个public 或protected的i,不定义其set get方法,而在子类中定义其set get方法,那么方法和i变量的联系也可以建立,也就是子类的set get方法和父类的i在类的定义和继承中建立了联系,这个大家应该很容易想的到了。
      3.因此得出结论,上例中get应该得到1;而不管子类的i为private还是public。因为set和get方法是与父类的i建立了联系的。
      

  16.   

    问题的关键在于多态:只有方法才能多态;变量是无所谓多态的。
    public class TestAnimal {
    public static void main (String [] args) {
    Horse b = new Horse();
    System.out.println(b.getI());
    b.setI(4);
    System.out.println(b.getI());
    }
    }class Animal {
    private int i=1;
    public int getI(){
    return get_i();
    }
    public void setI(int i){
    set_i(i);
    }
    protected int get_i(){
    return i;
    }
    protected void set_i(int i)
    {
    this.i = i;
    }
    }class Horse extends Animal {
    int i=3;
    protected int get_i(){
    return i;
    }
    protected void set_i(int v)
    {
    i = v;
    }
    }
      

  17.   

    关键是对继承后的内存情况要了解
    子类在构造的过程中要隐式的调用父类的构造函数
    所以内存中有一份父类变量的拷贝,既是super.i=1;
    然后又有一份子类内存变量的拷贝,是i=2;
    一种类在内存中只有一份方法的拷贝,则既是setI(),getI()
    我们调用b.getI的时候,关键是看这一份拷贝与那份内存变量拷贝
    发生联系,在这里是用父类的内存变量发生关系,所以返回的是
    super.i
      

  18.   

    1首先要澄清一点,父类的任何成员子类都继承了,只是访问的方式不同,是通过父类的方法访 问还是子类的方法
    2class Animal {
    public int i=1;
    public int getI(){
        
         return this.i;
    }
    public void setI(int i){
       this.i=i;
      
    }
    }
    b.getI()实际调用的是从父类继承过来的方法,但字类没有覆盖getI(),关键在于this,他实际上是一个Animal类型的引用,但实际指向的是b Horse类的实例,成员变量没有多态行为,只有隐藏,也就是说依据引用类型来确定调用哪个类的成员变量,而多态是依据引用所指向的类型确定调用方法
    在子类覆盖getI(),就会显示2
      

  19.   

    基本问题。多年的JAVA算白学了。
      

  20.   

    个人觉得好象也不是私有和public的问题,应该是分配空间的问题吧
    新手,学习!
    应该说两i虽然看起来是一样的,但实际的指向位置是不同的(不知道说的对不对)
      

  21.   

    把Animal 类的成员变量i  改为public,就可以输出2
    -----------------------------------------------------
    C#中没有这个问题,是不是BUG阿?
      

  22.   

    http://cache.baidu.com/c?word=qq%3B%B5%C7%C2%BC%3Bip%3B%BC%C7%C2%BC&url=http%3A//www%2E315ts%2Enet/viewtousu%2Easp%3Fid%3D4678%26cid%3D32022&b=10&a=0&user=baidu
      

  23.   

    to treeroot:
    要求透过父类“指针”去访问子类信息。所以,这个问题的要点就是理解“多态”是只适用于“方法”的概念。至于private还是protected,我甚至发现JAVA的编译器都会把关的。
      

  24.   

    这个问题不是很难,只是一些基础的东西。把JAVA的继承这个知识点弄清楚了就很容易了。
      

  25.   

    public class TestAnimals {
    public static void main (String [] args) {
    Horse b = new Horse();
    System.out.println(b.getI());
    }
    }class Animal {
    public int i=1;
    public int getI(){
    return i;
    }
    public void setI(int i){
    this.i=i;
    }
    }class Horse extends Animal {
    public Horse()
    {
    i=2;
    }
    }
    这样就可以输出2了。
    int i=2 ;是不能修改对子类变量,而是申请了一个新的变量
      

  26.   

    grant999(民) ( ) 正解,什么private子类没有继承,都是胡说八道,跟题目一点关系都没有。建议楼主看看类的载入与继承。子类实例化之前,父类已经被实例化,并且载入内存;由于animal类已经被实例化,且子类没有覆盖父类的getI()方法,那么调用getI()方法的时候,实际调用的是animal实例的该方法,所以返回1,你把animal的i修改为public的,也应该返回的是1;问题的关键有两点:
    1、父类已经被实例化;
    2、子类没有覆盖父类的getI方法;
      

  27.   

    关键是类对象隐含了一个this参数,在本例中,调用getI()方法是继承自父类Animal 的,因此,这个地方的this指向的Animal对象,所以返回1,与成员i声明为public或private无关。
      

  28.   

    你把animal的i修改为public的,也应该返回的是1;因为你在子类中重新定义了变量i(int i = 2),而并非修改父类i值;如果你把i前面的int去掉(i = 2),那么打印出来的才是2;
      

  29.   

    问题的关键就是,你重新定义了i,而非继承了i;所以你无法修改i值,打出来的就是1;你要是在子类中不重新定义i(直接i = 2),以你现在的private写法,会有编译错误的。不信你试试。
      

  30.   

    zhaoqiubo(赵小刀) 说的是对的,
    把子类i改为public也是不会返回2的,
    除非给子类添加getI()方法,才会返回2
      

  31.   

    由于子类没有覆盖父类的方法 所以getI()并没有多态性 故返回基类的getI()方法 如果把子类加上getI()方法后 无论基类中i是public private protected default 或者子类中i 是public private protected default 都会返回2 因为调用getI()时产生多态都是调用实际类(子类)的getI()方法。如果子类中没有定义i那么子类中的getI()方法会返回父类中i的值。这时如果父类中i被定义为private的话就会发生编译错误了
      

  32.   

    hoho~~说风凉话的人就不好了!期待更好的解释。
      

  33.   

    就这水平,还做了多年的java,说出来还不脸好!!!1、将private 改为 public
    2、将int i = 2 改为 i = 2
      

  34.   

    improgrammer(无忌)  正解变量没有多态
      

  35.   

    public protected private 
      

  36.   

    这是一个有关重载的基础问题,只要在Horse类中增加geti()方法就行了。
      

  37.   

    这是一个有关重载的基础问题,只要在Horse类中增加geti()方法就行了。
      

  38.   

    了解一下:在调用子类构造器时会调用父类的构造器(在C++中好像是说子类中包含有父类的实例,虚析构函数可以说明这个问题),如果没有重写getI,那只是调用了父类的一个方法罢了
      

  39.   

    了解一下:在调用子类构造器时会调用父类的构造器(在C++中好像是说子类中包含有父类的实例,虚析构函数可以说明这个问题),如果没有重写getI,那只是调用了父类的一个方法罢了
      

  40.   

    了解一下:在调用子类构造器时会调用父类的构造器(在C++中好像是说子类中包含有父类的实例,虚析构函数可以说明这个问题),如果没有重写getI,那只是调用了父类的一个方法罢了
      

  41.   

    变量被隐藏,方法被覆盖~最基本的JAVA问题
    用hibernate,spring ,struts的时候也记得看下JAVA基础
      

  42.   

    vagrant_xyz() ;正解.
    我想补充的是,从来没有父类的函数可以操作子类中新定义的成员的.而子类中的函数可以访问本身和父类的成员.非对称.
      

  43.   

    public class TestAnimals {
    public static void main (String [] args) {
    Horse b = new Horse();
    System.out.println(b.getI());//输出1
    System.out.println(b.i);//输出2  表明父类和子类中的两个i是不一样的.
    }
    }class Animal {
    public int i=1;
    public int getI(){
    return i;
    }
    public void setI(int i){
    this.i=i;
    }
    }class Horse extends Animal {
    int i=2;
    }
      

  44.   

    子类没重写getI()这个方法,所以得到的还是基类的I。
      

  45.   

    JAVA的乐趣就在这里。
    忽忽。
      

  46.   

    you can't overwrite the private paramerter
      

  47.   

    把Animal 类的成员变量i  改为public,就可以输出2,  这句话是不对!
    我运行了两次都是1。应该在子类中重写geti()方法去覆盖父类的这个
    方法,就可以得到子类i的值。关键还是要自己上机去运行,才能找到问题
    的所在。
      

  48.   

    这样写:
    public class TestAnimals {
    public static void main (String [] args) {
    Animal a = new Horse();
    Horse b = new Horse();
    a.setI(10);
    b.setI(5);
    System.out.println(b.getI());
    System.out.println("Animal.i = " + a.getI());
    System.out.println("Horse.i = " + b.i);
    }
    }class Animal {
    private int i=1;
    public int getI(){
    return i;
    }
    public void setI(int i){
    this.i=i;
    }
    }class Horse extends Animal {
    int i=2;
    }
    输出结果:
    5
    Animal.i = 10
    Horse.i = 2
    ========================
    楼主你就能知道, Animal 中的 private 和 Horse 中的i 是两个毫无关联的变量
      

  49.   

    改public 运行也是1  private也是1  我试了啊。
      

  50.   

    liudong9183() 大家都没人说他写的对,我觉得他写的是最好最正确,解释的最清楚的
      

  51.   

    liudong9183() 
    关键是对继承后的内存情况要了解
    子类在构造的过程中要隐式的调用父类的构造函数
    所以内存中有一份父类变量的拷贝,既是super.i=1;
    然后又有一份子类内存变量的拷贝,是i=2;
    一种类在内存中只有一份方法的拷贝,则既是setI(),getI()
    我们调用b.getI的时候,关键是看这一份拷贝与那份内存变量拷贝
    发生联系,在这里是用父类的内存变量发生关系,所以返回的是
    super.i
      

  52.   

    把Animal 类的成员变量i  改为public,就可以输出2   ???????????
    这是哪个版本的JDK编译出来的?谈谈我的想法:
    new Horse();之后,如果在Horse中找不到getI() 方法,
    就回去他的父类寻找,在Animal中找到getI()方法后,
    在父类取这个I,所以输出的值不受I定义为public还是private的影响,
    所以二者输出的都是 1
      
      

  53.   

    JAVA编辑思想里对这个问题阐述的非常清楚
      

  54.   

    在java 中成员变量不可以被覆盖,
    所以在 Horse b = new Horse();时,
    首先Animal的成员变量i被初始化为1,当Animal的构造器运行完后,Horse 开始初始化Horse里的变量i被初始化为2 ,但因为在继承时,成员变量并不能被覆盖
    所以Horse里面的i和Animal里面的i ,一点关系都没有,只是变量名一样而已。
    所以无论怎么该public 还是priate,结果都为1。
      

  55.   

    我也来说两句,首先看源码:这个类没有问题
    public class TestAnimals {
    public static void main (String [] args) {
    Horse b = new Horse();
    System.out.println(b.getI());
    }
    }注意这个类
    class Animal {
    private int i=1;
    public int getI(){
    return i;
    //注意:这里返回的是   this.i
    //所以即使是子类继承类父类的成员 i 父类应用的还是自己的 i。所以
    //输出的一定是 父类i 的值
    }
    public void setI(int i){
    this.i=i;
    }
    }class Horse extends Animal {
    int i=2;
    }
      

  56.   

    是个好问题!
    正好检验一下大家的基础是否牢固!真是百家争鸣啊!
    这里觉得zhaoqiubo(赵小刀)和ecaol的说法是对的。
    本人初学者没有什么发言权,仅是看看,学习知识!
      

  57.   

    这个问题很不错。
    事实上是这样的,即使i是public的
    输出结果也肯定是1
    因为成员变量并没有覆盖一说,也就是子类的i和父类的public 的i是共存在子类体内的。为什么输出的不是子类的i,因为你如果不覆盖public int getI()这个方法的话
    那么子类调用的其实是父类的getI()方法,java中的原则是调用的是哪个类的方,那么这个方法
    访问的就是这个类中的成员。也就是输出的肯定是父类中的i(无论父类i是public或private,也无论子类中是否也有i)
    这也说明了为什么在覆盖getI()之后就会输出的是子类中的i了,因为调用的是子类中的方法。
      

  58.   

    新手,还是学到了一些东西。
    跟着说几句:
    1.按照规范,成员变量应该是private,提供(方法)调用,而Horse的成员变量i是默认的访问权限,暴露了成员变量。
    2.将Animal的i改为public解决不了问题,也破坏了封装,显然不能用;好的解决方法应是将Horse的i也改为private,然后添加getI()方法提供访问。