public class test {    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        a.s = "[AA]";
        b.s = "[BB]";
        a = b;
        System.out.println(a.s);
        System.out.println(b.s);
        System.out.println(a.getS());// ??
        System.out.println(b.getS());
        System.out.println("====================");
        ((A)b).s = "[AA]";
        System.out.println(a.s);
        System.out.println(b.s);
        System.out.println(a.getS());
        System.out.println(b.getS());
    }
  }
class A {
    String s = "[A]";
    String getS() {
        return s;
   }
}class B extends A{
    String s = "[B]";
   String getS() {
        return s;
    }
}
/*输出结果[A]
 *   [BB]
 *   [BB]
 *   [BB]
 *====================
 *   [AA]
 *   [BB]
 *   [BB]
 *   [BB]
*/

解决方案 »

  1.   

    这是父类和子类有同名时的作用域的问题。此例程中的B类其实有两个s(继承父类自动得到的s,子类b自己定义的s),只是同名而已,但并不是同一个变量。但由于是同名,所以在b中已经无法访问父类的s了。在test.java中:
             a = b;//由于a是b的父类,所以用子类对父类进行赋值时,只会把子类中包含有父类的信息
                   //复制。但是这里b的s并非a的s,所以s并没有复制到a中。所以当a只是执行了一次构
                   //造函数,所以a.s是[AA]        System.out.println(a.s); 
            System.out.println(b.s);
            System.out.println(a.getS());// 这时调用的是a的getS(),并不是b的getS(),而根据
                                         //“a=b”的解释,此时的a是"[AA]"
            System.out.println(b.getS());
            System.out.println("====================");
            ((A)b).s = "[AA]";    //这句话是把b中的从父类继承下来的s赋值为“[AA]”,但并不是把
                                  //b的s赋值。
            System.out.println(a.s);
            System.out.println(b.s); //b.s是指b的s,并非b的父类的s。
            System.out.println(a.getS());
            System.out.println(b.getS());
      

  2.   

    haha,如果不是后期绑定,就不是多态 !
    public class test {    public static void main(String[] args) {
            A a = new A();
            B b = new B();
            a.s = "[AA]";
            b.s = "[BB]";
            a = b;//将b引用的内容,付给a,即相当于A a=new B(),向上转型.
            System.out.println(a.s);//调用的是A类里面的s,当然是[A]了.此时的a已经不等于"[AA]"的a了.
            System.out.println(b.s);//这个b还是b.s="[bb]"的b.所以答案为[BB].
            System.out.println(a.getS());// 虽然已向上转型,但是getS()方法已经被覆盖,所以调用的还是子类B的方法,即b.s.所以为[BB]
            System.out.println(b.getS());//这个不用解释了吧.
            System.out.println("====================");
            ((A)b).s = "[AA]";//向上转型.
            System.out.println(a.s);//而这里的a,还是a.s="[AA]"里面的a,所以结果为[AA].
            System.out.println(b.s);//这个不用解释.
            System.out.println(a.getS());//这个调用的还是子类的getS(),所以结果就是b.s即[BB].
            System.out.println(b.getS());//
        }
      }
    class A {
        String s = "[A]";
        String getS() {
            return s;
       }
    }class B extends A{
        String s = "[B]";
       String getS() {
            return s;
        }
    }
      

  3.   

    这样写的话,能清楚一些.
    public class Test {    public static void main(String[] args) {
            A a = new A();
            B b = new B();
             A a1 = new A();
             A a2 = new A();
            a.s = "[AA]";
            b.s = "[BB]";
            a1 =b;
            System.out.println(a1.s);
            System.out.println(b.s);
            System.out.println(a1.getS());// ??
            System.out.println(b.getS());
            System.out.println("====================");
            a2 =b;
            a2.s="[AA]";
            System.out.println(a2.s);
            System.out.println(b.s);
            System.out.println(a2.getS());
            System.out.println(b.getS());
        }
      }
    class A {
        String s = "[A]";
        String getS() {
            return s;
       }
    }class B extends A{
        String s = "[B]";
        String getS() {
            return s;
        }
    }
      

  4.   

    它的第一项为什么会 输出一个[A]  我认为是[A][A]啊
    我做拉的实验的是输出[A]啊
      

  5.   

    a.s = "[AA]";这句话 要不要 都是一样的结果啊 第一项 输出一个[A]
      

  6.   

    a = b;这一句将b引用的内容,付给a,即相当于A a=new B(),向上转型.
      而下面的打印里面的a.s指的是A类里面s的值.即A a=new B(),里面的引用a.已经不是a.s = "[AA]";里面的a了.
      

  7.   

    A a = new A();
            B b = new B();
             A a1 = new A();
             A a2 = new A();
            a.s = "[AA]";
            b.s = "[BB]";
            a1 =b;
            System.out.println(a1.s);
    看一下这里.我觉得解释的很清楚了.你的代码就相当于这个.当a=b后,就将引用改变了,此a以非原来的a了,而
            a.s = "[AA]";
            b.s = "[BB]";
    这两句只是对于a,b这两个引用来说s是这些.
    如果加一句在我的代码中System.out.println(a2.s);你看结果也是[A].
      

  8.   

    a=b 把b的引用给a ,b是子类所以b里面有自己的s和a类里面的s,
    但是由于是向上转行,所以a.s的值不是由b里面的s赋给,
    而是由b的父类的s赋给(他门是同名),而b父类里面的s是由a初始化时赋给的/
    我说的对吗?
    是不是我的理解有点差啊 ?
    我还是没听懂
    a = b;这一句将b引用的内容,付给a,即相当于A a=new B(),向上转型.
    而下面的打印里面的a.s指的是A类里面s的值.即A a=new B(),这都是一样的啊!
    a.不是a.s="[AA]",那是什么呢?
      

  9.   

    System.out.println(a2.s);你看结果也是[A].
     这个说明a.s="[AA]"只是a引用所对应的s值.而a=b,则是改变了a,换句话说就是将a变为a1了.
      

  10.   

    其实是不是多态不重要,重要的是搞清楚来龙去脉!我认为这是多态问题.想搞清楚这个问题首先要搞懂继承的内存分布情况,即A ,B 初始化后,由于 B 继承 A 后,B 的内存块里面有新的和A 类初始化后一样的一内存块,而不是和 A 共享一块内存!A a = new A();
    B b = new B();
    a.s = "[AA]";
    b.s = "[BB]";执行到这里(请注意是执行完这几句话)之后内存分布如图:class A                       class B
    __________                   __________
    | s=[AA] |                   | s=[A]  |
    | getS() | <--- a            | getS() |  <---- b
    ----------                   ----------
                                 | s=[BB] |
                                 | getS() |
                                 ----------a 和 b 分别指向class A 和 class B 的一个对象,而当执行完 a = b; 之后内存分布情况如下:class A                       class B
    __________                   __________
    | s=[AA] |                   | s=[A]  |
    | getS() |                   | getS() |  <---- b
    ----------                   ----------
                                 | s=[BB] |  <---- a
                                 | getS() |
                                 ----------
    a 和 b 指向的是同一个class B 的对象,由于 B 的s与 A 的s 重名,所以 b.s 的是B自己(上半部分)的s,b.getS()也返回自己的s,b不能访问基类的s和getS(); 而对于a,由于执行了a=b,(即效果等同于 a=new B()),所以由于多态的原因,a.getS()其实执行的还是B原来有的(下半部分的)getS(),而a.s()则只能访问自己的s,(即上半部分的[A]),所以前边四个输出是
    [A]
    [BB]
    [BB]
    [BB]
    ((A)b) , b将会的upcast(向上转型),所以((A)b).s 改变的只是 class B 上半部分的 s 的值,所以a访问到的只能是自己(上半部分的被改变为[AA]的s值),下边就不用解释了.
      

  11.   

    A a = new A();
    B b = new B();
    a.s = "[AA]";
    b.s = "[BB]";执行到这里(请注意是执行完这几句话)之后内存分布如图:class A                       class B
    __________                   __________
    | s=[AA] |                   | s=[A]  |////这里开始是s=[B]啊
    | getS() | <--- a            | getS() |  <---- b
    ----------                   ----------
                                 | s=[BB] |
                                 | getS() |
                                 ----------
      

  12.   

    是啊,通俗点可以说 class B 的内存里包含一段数据,这段数据和 class A 内存包含的数据相同, class B 由两部分组成,即
    1.复制的 class A 一部分(是另外开辟一块新内存,人后把复制的 class A 的那部分粘贴过来)
    2.自己的数据一部分
      

  13.   

    ...问题越搞越复杂,其实人家就想知道System.out.println(a.getS());// ??
    整个程序与多态无关