01.public class A{  
02.  
03.    public String s = "A";  
04.  
05.    public void setS(String s){   
06.        this.s = s;   
07.    }   
08.  
09.    public String getS(){   
10.        return this.s;   
11.    }  
12.      
13.}  
14.  
15.public class B extends A{   
16.  
17.    public String s = "B";  
18.  
19.    public void setS(String s){   
20.        this.s = s;   
21.    }   
22.  
23.    public String getS(){   
24.        return this.s;   
25.    }  
26.      
27.    public static void main(String[] args){   
28.        A a = new A();   
29.        B b = new B();   
30.        a.setS("[AA]");   
31.        b.setS("[BB]");   
32.        a = b;  
33.        System.out.print(a.s);  
34.        System.out.print(b.s);   
35.        System.out.print(a.getS());   
36.        System.out.print(b.getS());   
37.        }  
38.}//输出的结果  

解决方案 »

  1.   

    A[BB][BB][BB]?
    我的理解
    a = b;那么这句就作废了a.setS("[AA]"); 
    b.setS("BB");所以b.s ="BB"; 
    所以a.s 取出来的是自己的a.s="A"
    b.s ="[BB]";
    System.out.print(a.getS());这句话被子类复写了,打印[BB]
    System.out.print(b.getS());这个很明显是[BB]
      

  2.   

    A
    [BB]
    [BB]
    [BB]
    重写多态那些事...
      

  3.   

    B类继承A类,B类重写了A类的setS()与getS()方法,java中的多态支持重写,所以当父类的引用a指向子类b时,a,b都是调用了B类重写后的方法,故后三个输出[BB];
    属性不支持多态,但可以被覆盖,A类中的s与B类中s各自属于各自的类,a的引用指向b时,由于a类型仍然为父类A,那么a.s指向为父类的this.s,输出A,为什么一开始a.setS("[AA]")不管用了?因为a重新指向了,原来的new A()和a已经没有任何关系了
      

  4.   

    a.s指向为父类的this.s??这个怎样才能更好的理解呢??
      

  5.   

    多态就是父类的引用指向子类的对象
    例如 A a =  new B();
    使用多态以后 ,如果子类B中重写了父类A的某些方法 ,那么a在调用那些被重写的方法的时候,其实执行的是B类的方法 , 属性不支持重写,如果B中某个属性和A中类型相同、名字相同,当使用a.a这种方式访问的时候,访问的是A类中的a属性。但是调用a.getA()方法的时候,应为B类中重写了该方法,所以实际上执行的是B类中的getA()方法,所以返回的是[BB]
      

  6.   

    真把我考住了,因为我们从来没有定义过公共的属性,
    a= b 应该是a 的引用和b相同,
    所以,a的访问的属性和方法,都和b一样了。
    输出应该全是BB吧
      

  7.   

    《Java编程思想》第四版,P156页,有一样的类型但是也没有说清楚怎么回事!如下
    8.25缺陷:域与静态方法class Super{
    public int field = 0;
    public int getField(){return field;}
    }class Sub extends Super{
    public int field = 1;
    public int getField(){return field;}
    public int getSuperField(){return super.field;}
    }public class FieldAccess{
    public static void main(String[] args){
    Super sup = new Sub();//Upcast
    System.out.println("sup.field=" + sup.field +
    ",sup.getField()=" + sup.getField());
    Sub sub = new Sub();
    System.out.println("sup.field = " + sub.field +
    ", sub.getField() = " +sub.getField()+
    ", sub.getSuperField()= " + sub.getSuperField());
    }
    }/*Output
    sup.field = 0,sup.getField() = 1
    sub.field = 1,sub.getField() = 1, sub.getSuperField() = 0
    *///;书中解释如下:
        当Sub对象转型为Super引用时,任何域访问操作都将由编译器解析,因此不是多态的。在本例中,为Super.field和Sub.field分配了不同的存储空间。这样,Sub实际上包含两个称为field的域:它自己的和从Super处得到的。然而,在引用Sub中的field时所产生的默认域并非Super版本的field域。因此,为了得到Super.field,必须显示的指明super.field.
        尽管这看起来好像会成为一个容易令人混淆的问题,但是在实践中,它实际上从来不会发生。首先,你通常会把所有的域都设置成private,因此不能直接访问它们,其副作用只能调用方法来访问。另外,你可能不会对基类中的域和导出类中的域赋予相同的名字,因此这种做法容易令人混淆。
        大家谈谈是不是没有解释清楚??
      

  8.   


    这才是关键!属性不支持重写,并且a.a这种方式访问的时候,访问的是A类中的a属性。
      

  9.   

    为什么a.setS("[AA]");这句作废了呢?它不是在a=b;之前执行的?  
      

  10.   

    引用 2 楼 的回复:
    A[BB][BB][BB]?
    我的理解
    a = b;那么这句就作废了a.setS("[AA]"); 
    b.setS("BB");所以b.s ="BB"; 
    所以a.s 取出来的是自己的a.s="A"
    b.s ="[BB]";
    System.out.print(a.getS());这句话被子类复写了,打印[BB]
    System.out.print(b.getS());这个很明显是[BB……为什么a.setS("[AA]");这句作废了呢?它不是在a=b;之前执行的?  
    同问啊?解释清楚点!
      

  11.   

    子类创建实例时会创建一个隐含的父类实例。
    b.setS("BB");只是使b.s ="BB",其父类的s还是A
    a.s指的是父类的s
      

  12.   

    我晕啊a = b;明明是父类引用指向子类引用~a = new B();这个是父类引用指向子类对象~如果这样的话结果又不一样了~看来我基础还是很不牢靠啊
      

  13.   

    这些书里的东西  很多都是如果你事先不明白 那就没办法看懂 一旦明白了  才能看懂  
    就这个问题 Super sup = new Super();
              Sub sub = new Sub();
              sup = sub;
    父子类中 同时存在 A属性  和getA()方法;
    当sup.A属性时,属性为静态绑定 没有多态特性,所以你用sup父引用.A属性时  虚拟机直接去父区里找A属性;
    当sup.getA()方法时,方法时动态绑定 有多态特性,所以虚拟机先去子区找getA()方法  只有在子区找不到getA()方法时,才会去上一级父区里找getA()方法。
    这就是属性和方法的区别  也是静态绑定 和 动态绑定的区别;
    就Super类 和 Sub类的内存图
    |-------------|
    |   Object    |
    |-------------|
    |   Super     |
    |   int A;    |
    |   getA();   |
    |-------------|
    |   Sub       |
    |   int A;    |
    |   getA();   |
    |-------------|
    在new Sub()对象中:
    访问 Super中的A属性    sup.A;
    访问 Sub中的A属性       this.A;
    访问 Super中的getA()方法   super.getA();(这时如果用sup.getA(),访问的则是Sub中的getA()方法)
    访问 Sub中的getA()方法     this.getA();
      

  14.   

    遇到这样的问题画一画内存图就很容易解决了:
          A a = new A();   有了个a  里面有个s "[AA]"
         B b = new B();   有个b   里面有个s "[BB]"
         a = b;           把b的指针传给a 但是要是调用a.s的话还是自己的s
         a.getS() 的话就是调用子类的了,因为构成了重写。
      

  15.   

    就是属性不支持多态,多态调用的只是方法。
    A a = new b();
    调用的属性是基类的,调用的方法是子类的。
    a = b ; 应该是a 和 b 这两个引用都会指向共同一个new 出来的对象。
    画内存图应该很了
      

  16.   

    a=b,a指向的是B类对象
    B类对象只是改变B类中的字符串s,A类s字符串没有变,但是方法覆盖一定是访问B类的getS()方法返回B类的s字符串
    A
    [BB]
    [BB]
    [BB]