今天我遇到一个在网上看到的问题,可是我反复运行编译,就是不理解其中的道理,希望各位老师给予解答,谢谢
题目是这样的:
class A

  int a = 1;
  int b;
  void f()
  {
    System.out.println("abc");
  }
}
 
class B extends A
{

  double a = 2.1;
  double b;
  void f()
  {
    System.out.println("ABC");
  }
}
public class ExtendsTest
{
  public static void main(String[] args)
  {
    A x1 = new A();
    B x2 = new B();
    System.out.println(x1.a);
    x1 = x2;
    System.out.println(x1.a);
    System.out.println(x2.a);
    x1.f();
  }
}
运行结果:
1
1
2.1
ABC疑问:x1=x2后,为何输出的x1.a仍为1,而x1.f()却为ABC
这里的对象的引用之间是怎么赋值的呢?请老师详细解答
 
还有一个疑问:继承   我们知道继承其实就是类的复制
那么A继承了B,是不是里面的方法和字段都继承呢?一开始对上面的问题我是想通过继承来解释
B继承了A,那么B.f()就是"ABC",当x1=x2;
A.f()也就是"ABC"
可是x1.a却没有改变,那么通过继承也是解释不通的我是一位刚学JAVA的学生,可是这个对象的引用问题就是搞不懂,可能问题很简单,也请各位老师能给我详细解答说明下,再次感谢

解决方案 »

  1.   

    x1=x2之后
    x1指向x2的对象,也就是一个B实例,可这里x1声明为A,也就是他的编译期类型仍然是A
    我们知道,对于变量,没有覆写和多态,x1.a就是按照他的编译期类型来调用,仍然是1但是方法有覆写,也就有多态的效应,x1现在指向一个B对象,也就是x1的真实类型是B,根据多态,
    x1.f()方法将调用B类的版本,打印ABC继承,封装,多态.OO的基本概念找本书了解下为好.
      

  2.   

    楼上回答的非常对其实就是这样理解,我给你总结总结吧:
    在多态机制中:
    调用成员变量时,将调用引用类型所对应的类中的成员变量的,如果该类中没有定义的该变量,才会调用父类(有定义)的同名成员变量。
    调用成员方法时,将根据对象的运行时的类型来确定调用哪个成员方法,也就是说运行时类型是哪个类的引用,就调用哪个类中定义的成员方法在你的例子中已经实现了多态机制
    class B extends A
    A x1 = new A();
    B x2 = new B();//(3)
    System.out.println(x1.a);//这里运用对一条规则就得出1
    x1 = x2;//这相当是定义了一个父类的引用,但其对象是子类
    //下面这些就好理解了
    System.out.println(x1.a);//这里还是调类A的a
    System.out.println(x2.a);//这里根据语句(3)知道谳用的是B类的a
    x1.f();//而这个因为x1=x2相当于A x1=new B()根据多态的动态绑定(规则2)调用的就是x2.f()了