class tes{
 public static void main(String[] args)
{
     a a1=new b;
     System.out.println(a1);
}
}
class a{int a=10;}
class b extends a{int a=20;
}
上面这段代码,会打印出10,但是根据java的动态绑定机制,a1实际类型其实是b 打印结果应该是20,那为什么实际结果是10呢?

解决方案 »

  1.   

    你可以参考臧圩人的 JAVA面试题解惑系列合集 pdf文件的第三章“JAVA面试题解惑系列(三)——变量(属性)的覆盖”
      

  2.   

    父类和子类定义相同的属性,子类不会覆盖父类的属性。你的代码中a1是a类型的,a1.a自然就是指向a类中的属性,如果吧main方法改为下面,就可以调用子类的属性了
    public static void main(String[] args)
    {
    a a1 = new b();
    b a2 = (b) a1;
    System.out.println(a2.a);
    }
      

  3.   

    相当于在内存中new 了b的空间里面有两个a,但是父类只能指向自己 的那个变量。我也是初学者我的理解是这样的
      

  4.   

    传智播客2013年8月javaEE+物联云就业班分享:http://pan.baidu.com/s/11NOyJ
      

  5.   

    如果要输出结果为10的话,LZ应该用System.out.println(a1.a);
    a a1 = new b();   //这句LZ也写错了
    子类创建的对象赋值给父类对象,这时候a1被称为上转型对象,上转型对象调用变量时调用的是父类的,不能使用子类的变量。
    如果把b类中的变量a改为b,无法使用a1.调用变量b。
    如果想要输出20的话,可以将上转型对象强制转换成子类的对象:b b1 = (b) a1;
    然后输出System.out.println(b1.a);  就是20了
      

  6.   

    我就不明白了,楼主写错的程序,楼上的这么多人怎么得出来的10?难道不是:类名@地址 
    好吧,我较真了。一句话:域、静态方法、private方法都不是多态的,只有普通方法才可以是多态的。
      

  7.   

    给你个例子:
    class Base{
        int count = 2;
    public void display(){
    System.out.println("Base==="+this.count);
    }
    }
    class Derived extends Base{
    int count = 20;
    @Override
    public void display(){
    System.out.println("Derived==="+this.count);
    }
    }
    public class FieldAndMethodTest {
    public static void main(String args[]){
    Base bd = new Derived();
    System.out.print(bd.count+"=====");
    bd.display();

    }
    }
    该输出结果为:2=====Derived===20
    原因:java继承中对成员变量和方法的处理时不同的,子类重写父类方法,会彻底覆盖了父类的同名方法,但是即使子类定义了与父类完全同名的实例变量,这个实例变量依然不可能覆盖父类定义的实例变量,所以,你可以记住下面这个结论:
    对于一个引用型的变量(bd)而言,当通过该变量访问它所引用的对象的实例变量(如count)时,该实例变量的值取决于声明该变量时的类型(bd声明时是Base类型);当通过该变量来调用它所引用的对象的方法(display)时,该方法行为取决于它所实际引用的对象(bd实际对象类型是Derived)的类型.
    谢谢,希望能帮到你
      

  8.   

    建议楼主亲自查下,JDK对方法与变量继承的不同处理机制。
      

  9.   

    我理解的多态就是“多种状态” 能有多种状态的一般都是方法,变量不会有多态情况
       还有  new对象的时候有(),那个表示调用构造函数的不能掉,
             输出的时候直接调用a1会显示地址值,显示数字的话应该用a1.a
      建类的时候 尽量大写 ,可能因为我也是新手所以比较注意这些
      

  10.   

    public class testExtend {
    /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    a a1=new b();
        System.out.println(a1.a);
        a1.printout();
    }
    }
    class a{
    int a=10;
    public void printout(){
    System.out.println("a");
    }
    }
    class b extends a{
    int a=20;
    public void printout(){
    System.out.println("b");
    }
    }