黑马程序员技术交流社区

标题: 转型的问题 [打印本页]

作者: 汤密奕    时间: 2012-7-6 20:22
标题: 转型的问题
本帖最后由 汤密奕 于 2012-7-6 22:31 编辑

public class J_Test extends J_Base{

        /**
         * @param args
         */
        public void mb_method()
        {
                System.out.println("Test");
        }
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                Object a = new J_Test();
                ((J_Base)a).mb_method();

        }

}

class J_Base
{
        public void mb_method()
        {
                System.out.println("Base");
        }
}

打印结果是子类的方法:Test,为什么不是父类的Base,不是转型了么
作者: 罗磊    时间: 2012-7-6 20:35
简单说!你的子类方法把父类的方法复写了!
作者: 孙飞    时间: 2012-7-6 20:47
  1. public class J_Test extends J_Base
  2. {
  3.        public void mb_method()//复写父类的方法
  4.       {
  5.              System.out.println("Test");
  6.        }
  7.       public static void main(String[] args)
  8.      {
  9.             Object a = new J_Test();//建立一个Object类引用的子类对象
  10.             ((J_Base)a).mb_method();//把引用变量a向下强转为父类的引用变量,这句在编译的时候要看父类的引用变量,也就是看父类中是否有mb_method()方法,但在执行的时候要看子类,也就是要执行子类中的方法,所以打印的是Test

  11.      }
  12. }
  13. class J_Base
  14. {
  15.      public void mb_method()
  16.     {
  17.           System.out.println("Base");
  18.     }   
  19. }
复制代码

作者: 汤密奕    时间: 2012-7-6 21:04
罗磊 发表于 2012-7-6 20:35
简单说!你的子类方法把父类的方法复写了!

是复写了啊,但是((J_Base)a).mb_method();不是指把a强制转成了J_Base么,那a.mb_method()应该调用的是父类的方法,强转到底是咋回事啊?有点乱。。。

((J_Base)a).mb_method();等同于J_Base b =(J_Base)a;   b.mb_method();
我在J_Base这个方法中加个mb_method1()方法,b.mb_method1()可以调用父类的方法
莫不是子类有就调用子类,没有就调用父类么?

我的理解却是b已经被转成了J_Base这个对象,那应该调用的是J_Base这个方法,与重写不重写没多大关系吧



作者: 万宝东    时间: 2012-7-6 21:06
Object a = new J_Test(); 这种方式,实际上是实例化了子类的对象,注意:内存中还是子类对象。
((J_Base)a).mb_method(); 表面上看起来是父类对象了,但是由于内存中是子类对象,所以调用的还是子类方法。
虽然上溯造型到了父类,由于子类重写了父类的方法,调用的还是子类的方法(也就是说:方法的实现,最后是在子类中实现的)。

所以,总结如下:
如果子类没有重写父类的方法,调用父类的方法的时候,实际上是去父类的内存中实现,可以调用父类方法。
如果子类重写了父类的方法,那么,你虽然上溯造型到了父类,由于内存还是子类,该方法的实现还是在子类,所以用实例化的对象是调用不到父类的,这种情况下,只能用super关键字。

作者: 汤密奕    时间: 2012-7-6 22:18
万宝东 发表于 2012-7-6 21:06
Object a = new J_Test(); 这种方式,实际上是实例化了子类的对象,注意:内存中还是子类对象。
((J_Base)a ...

明白了,谢了哈,父类没有在堆内存中new一个实例,a实际上是指向了子类的实例,根据你的描述,我画了个图


变量a在引用实例时,先找子类的方法,没有再找父类的引用





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