黑马程序员技术交流社区

标题: 多态小问题 [打印本页]

作者: 沈子豪    时间: 2013-3-13 10:43
标题: 多态小问题
本帖最后由 沈子豪 于 2013-3-13 12:05 编辑

class A
{
  void fun1()
  {
    System.out.println(fun2());
  }
  int fun2()
  {
    return 123;
  }
}
class B extends A
{
  int fun2()
  {
    return 456;
  }
  public static void main(String argv[])
  {
     A a;
     B b = new B();
     b.fun1();
     a = b;
     a.fun1();
  }
}

打印结果是456
                 456
具体的分析过程应该是怎样的?

作者: 丁一    时间: 2013-3-13 11:12
本帖最后由 丁一 于 2013-3-13 11:16 编辑

是不是这样的? 个人理解
      A a;                        定义一个a   
     B b = new B();      定义b 并初始化
     b.fun1();               执行fun1(), 因为是继承a 所以有这个方法   输出 456
     a = b;                   a初始化  等于b
     a.fun1();                执行a.fun1()        调用的是b中的方法   同样输出456  这个地方是 因为上面有 a=b 了,所以执行 b中的 fun2   ,如果删除a=b 会出错 需要改成 A a=new A();这样就输出 456  123

作者: 刘国涛    时间: 2013-3-13 11:30
class A
{
   void fun1()
  {
     System.out.println(fun2());
   }
   int fun2()
   {
     return 123;
   }
}
class B extends A
{
  int fun2()
   {
     return 456;
   }
   public static void main(String argv[])
   {
      A a;
      B b = new B();
      b.fun1();//类B中的fun2方法会覆盖类A中的fun2方法,输出456
      a = b;//类A的引用指向实体对象new B(),
      a.fun1();//相当于调用类B中的fun1方法,输出456
   }
}
作者: 沉默de羔羊    时间: 2013-3-13 11:54
本帖最后由 沉默de羔羊 于 2013-3-13 12:57 编辑

都解决了,那我就把上午的内容清空了!

作者: scott0610    时间: 2013-3-13 12:07
本帖最后由 袁见 于 2013-3-13 12:10 编辑

分析过程:
A a;定义一个引用类型的变量a,并未初始化该变量。
B b = new B();创建一个B对象,B类是A类的子类,根据Java中的继承关系,B类将获得A类中的所以成员属性(处了私有属性外)。
执行b.fun1();时,A类的fun1方法调用了fun2方法,而fun2在子类B中重写了该方法,所以将会打印出456。
a=b;这时将b对象赋值给a对象,父类的引用指向子类对象,将存在多态。
因为子类其实是一种特殊的父类,因为Java允许把一个子类对象直接赋给一个父类引用变量,无须任何类型转换,或者被称为向上转型,向上转型是由系统自动完成的。
Java引用变量有两个类型,一个是编译时的类型,一个是运行时的类型。编译时的类型是由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就会出现所谓的多态。
在编译时fun2方法应该加载的是父类的fun2方法,当运行时,因为子类B重写了父类的fun2方法,所以在运行时将执行子类的fun2
所以这里也会打印出456、

希望对你有所帮助。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2