日期:2009-07-02  浏览次数:20486 次

JAVA多态性<==>我和网友交流实录    zosatapo(原作)
关键字    Java 多态性 面向对象


我在这里公开和我dennisboys的学习交流信件,我们主要在谈java中多态性问题。
这里感谢我的好朋友能给我一个结合自己能力解释问题的机会,在解释中有出错
或者需要讨论的部分希望能通知我一声。
上篇关于多态性的文章请参阅我前面写的<<java多态性实例解释一文>>.

*******************************************************************************
    网友dennisboys的提问部分开始
*******************************************************************************
从头到尾把你的代码看了n次,画了n个图(关于父类和子类的函数地址图),有以下一些迷惑
test t=new test();
base b=new base();
b=t;
/*
问题一:
这里是把父类的引用指向子类,那是不是说调用父类的方法就等于调用子类的方法呢?就是
如果b.display2()不是调用子类的display2()方法吗?而子类有display2()方法,为什么不能
调用呢?(我试过写代码了,果然如你所说是出错的。)
对于以上的问题,你有一段文字好像是对其作解译的。不过我不太清楚。不知是不是以下这
段。
引用原文:
同时可能有人要问,子类中那个函数地址不是也在虚拟函数表中吗?
很高兴你问这样的问题,但是父类引用看到的虚拟函数表是没有
那个函数项目的,因为他对于父类引用绝对是不可见。
我现在理解是如果在子类中如对方法作了更改或新增的方法,对父类来说是不可见的?理解
对吗??
*/
问题二:
((test)b).display();
另一个迷感就是你说的强制转换类型的语法到底是怎样的??我不明白为((test)b)代表什么

不过说回来(我怎么觉得这个例子是在说继承??),这个例子使我对继承有了很深的认识
,我倒是觉得对多态性还是一知半解,(别说我笨笨)可能我还没清楚到底哪用到了多态性,
不过请先回复了我以上两个问题,希望你回复了我以上两个问题(结合我研究你的代码)使我
对多态性有更好更深的认识。。
*******************************************************************************
    网友dennisboys的提问部分结束
*******************************************************************************

*******************************************************************************
    zosatapo的解释部分开始
*******************************************************************************
你真的应该谢谢我的,因为我辛辛苦苦打了篇文章,
因为网络原因没有能成功保存,害了我重写一次,
没有办法,谁叫你是我的好朋友呢。
首先谢谢你耐心看完我的文章。
下面我就我上次写的那篇文章和你的问题作简单的说明但是又比较复杂的说明。
我上次写的那篇文章存在一处写作错误,我在网上已经修正了,这里告诉你一下:
上次的原文中有这样的几句话
****************************************
  // 下面调用会出错的
  file://t.display2();
  file://应该象下面那样
  ((test)b).display2();
******************************************
这几句话写作上有错误:
应该改成成下面这样:
**********************************************
  // 下面调用[不]会出错的  (这里多了一个[不]字)
  file://t.display2();
#########################################  
  实际上我上面这两行跟本文没有关系的
  但是为了你很好的理解动态性,你可以
  把上面的代码与下面的进行比较。
#########################################
  file://下面这行调用不会出错
  file://b.display2();  这里加了一行
  file://应该象下面那样
  ((test)b).display2();
**********************************************‘

下面正式开始我们今天的话题,正对你的问题我进行解释,
这里我尽可能的解释详细一点让你明白,实际上这里太复杂
涉及到OOP的具体实现问题,这个问题又不得不涉及到编译器
问题,主要的又是对象内存布局问题。
由于第二个问题比较简单,我把回答问题的次序颠倒一下。
*********
  问题二
*********
你说的很对,我这里解的是继承,但是我这里解的不仅仅是继承的
问题。可以这样是你说的继承只是我解释动态性问题的一个途径和
手段而已,因为继承和多态性一样是面向对象中很重要的概念,不
是写一点文章就可以说明白的。
简单一点和不精确的说,动态性与是继承不可分割的,如果没有继承
根本就谈不上多态性的。所以我说你说的对,但是你没有真正明白我
例子的作用(55555555~~~~~~~~~~~~~我的心血呀)
*********
  问题一
*********
首先需要说明的是你对这个问题的理解是不正确的。
这个问题更是复杂的一塌糊涂,我尽量用一些不标准的词汇来说明这个问题。
因为这样便于理解。我这里不解太多的理论,因为我自己现在也正在研究jvm
规范的,因为很多东西java和c++不同,虽然两者实现很相似。上面这点,
我是根据我个人的一些实践,包括理论方面和程序编写实践得到的。但是
我也不敢全部拿c++的那套实现讲给你听,实际上讲了你也不一定听得懂的。
我这里主要讲一些基本的知识,你记住就可以了的,等你学习深入的时候
我再给解释,也许那时候你自然就懂了。
实际上在继承以后,子类会重新设置自己的虚拟函数表,
这个虚拟函数表中的项目有由两部分组成。从父类继承