Java多态中的方法覆盖
多
态 (Polymorphism) 大家应该都不陌生,它是我们开发面向对象系统的“老朋友”了
。但是老朋友也会有“烦心”的时候啊,呵呵。有时候不注意,还真会被它难到。譬如下面这个例子,大家可以先不看下面的答案,在自己脑海中运行一道,看看自
己想的跟实际结果是否相符。
java 代码
- publicclassPolymorphism{
- publicstaticvoidmain(String[]args){
- Ab=newB();
- b.fb();
- }
- }
-
- classA{
- publicA(){
- }
- publicvoidfa(){
- System.out.println("CLASSA:FunctionfaRuning......");
- }
-
- publicvoidfb(){
- System.out.println("CLASSA:FunctionfbRuning......");
- fa();
- System.out.println("CLASSA:FunctionfbStop......");
- }
- }
-
- classBextendsA{
- publicB(){
- }
- publicvoidfa(){
- System.out.println("CLASSB:FunctionfaRuning......");
- }
-
- publicvoidfb(){
- System.out.println("CLASSB:FunctionfbRuning......");
- super.fb();
- System.out.println("CLASSB:FunctionfbStop......");
- }
- }
下面是它的运行结果:
CLASS B :Function fb Runing......
CLASS A :Function fb Runing......
CLASS B :Function fa Runing......
CLASS A :Function fb Stop......
CLASS B :Function fb Stop......
怎么样,猜对结果了吗?如果结果跟你想象的一模一样,那么恭喜你,你对多态已经有初步了解了,起码在语法层次上是比较熟悉了。但是,千万不要“洋洋得意”,你可否解析结果为什么会是这样吗?我们可以先来梳理一下程序流程:
1、运行main函数,创建B对象,调用B的方法fb,于是打印出"CLASS B :Function fb Runing......",都在情理之中。
2、执行super.fb(),调用父类A的方法fb,首先打印出"CLASS A :Function fb Runing......",预料之中
3、执行方法fa(),打印出"CLASS B :Function fa
Runing......",呃?奇怪了,为什么不是执行A的方法fa(),而是子类B中的fa()呢?当前被执行的是类A的方法,那么虚拟机找到的应该
是A类的Method Table,找到的应该是A类的方法fa()啊?难解~
4、打印"CLASS A :Function fb Stop......",返回
5、打印"CLASS A :Function fb Stop.....",返回,程序结束。
现在问题清楚了,就是虚拟机在执行类A方法的时候查找的Method
Table竟然是子类B的。为什么呢?其实,只要我们清楚java方法调用的方式,这个问题就迎刃而解了。在Java虚拟机中,每启动一个新的线程,虚拟
机都会为它分配一个Java栈,而每当线程调用一个java方法时,虚拟机就会在该线程的java栈中压入一个新帧,用以存储参数,局部变量等数据。我们
将这个正在被执行的方法称为该线程的当前方法,其相应的栈帧为当前帧。
好了,当我们调用一个方法时,我们需要往当前帧中压入哪些参数呢?简单,方法的参数列表中不是都说得清清楚楚的吗?嗯,对于C语言来说,这个说法是正确
的,但是对于诸如C++,Java,Python等面向对象语言来说,却是不对的。大家还记得那个"this"指针吗?!不错,在Java中,所有的实例
方法(Instance
Method)调用的时候都会把当前对象压入当前帧中,Java虚拟机正是通过这个参数来决定当前所使用的类(通过判断该对象的类型)。
在上面的例子中,main中调用b.fb()时,压入的当前对象自然是B类对象,我们记为b。在B的fb()中调用super.fb()时,压入的就是刚
刚压入的对象,也就是b了。同样,在A的fb中调用fa()时,压入的也是b。因此,在使用
invokevirtual指令调用fa()时,找的就是B的方法表(当前对象b的类型为B),也就执行了类B的fa了。
这种现象在构造函数中特别常见,因为构造函数中会隐含使用调用父类的构造函数的,如果在父类的构造函数中调用了实例方法(如
A的fa),而在子类中又覆盖了这个实例方法(如
B的fa),那么得到的结果往往不是我们所要的。因此,我们最好不要在构造函数中使用多态方法,不然,Debug会很痛苦的:)
某朋友的blog:http://blog.csdn.net/changemyself/archive/2006/11/21/1402507.aspx
分享到:
相关推荐
网页BlogJava
此文档主要是tomcat中MySQL连接池配置 - feng - BlogJava
在IT行业中,网络爬虫是一种常见的技术,用于自动地抓取网页内容,为数据分析、信息检索等任务提供数据源。本项目"BlogJava博客文章爬取代码"专注于使用Java编程语言来实现对BlogJava博客平台的文章内容进行爬取。...
package com.hyq.test; import java.util.Properties; import javax.mail.*; import javax.mail.internet.*; public class MailExample { ... public static void main (String args[]) throws Exception { ........
在BlogJava博客文章爬取项目中,可能根据博客的结构和内容需求,结合了DFS和BFS。例如,DFS可能用于深入挖掘每个博主的文章,而BFS则可能用于遍历首页的推荐文章列表。通过这样的混合策略,爬虫可以更高效地抓取到所...
ruby查缺补漏 - 庄周梦蝶 - BlogJava
**超详细注释基于BlogJava主页的Java爬虫程序** 在信息技术领域,网络爬虫是一种自动化获取网页数据的工具,广泛应用于数据挖掘、搜索引擎索引和数据分析等场景。本项目是一个针对BlogJava(一个知名的Java技术交流...
Struts+Spring+Hibernate的完美融合BlogJava.mht
│ │ └─blogjava │ │ └─mobile │ ├─gen │ │ └─net │ │ └─blogjava │ │ └─mobile │ ├─res │ │ ├─drawable │ │ ├─layout │ │ └─values │ └─src │ └─net │ └─blogjava ...
3. **buildRendering()** 和 **postCreate()**: 这两个方法在Widget生命周期中起到关键作用。`buildRendering()` 是初始化渲染阶段,用于设置DOM元素和初始样式。`postCreate()` 则在渲染完成后调用,用于进一步的...
- **使用putExtra方法**:可以在启动Intent之前,通过`putExtra`方法添加额外的数据到Intent中。 示例代码如下: ```java Intent intent = new Intent("net.blogjava.mobile.MYACTION"); intent.setData(Uri.parse...
最近总结手上下到的电子书,一看还真是多,全是精品,虽知大家都有了,仍不敢独食
在本文中,我们将探讨如何使用Ajax技术来自动加载BlogJava和博客园的RSS feed内容。Ajax(Asynchronous JavaScript and XML)是一种在不刷新整个页面的情况下更新部分网页的技术,通过JavaScript与服务器进行异步...
根据提供的文件信息,本文将对《JAVA2简明教程》中的课后习题答案与实验源码进行详细解析。此教程适用于Java初学者以及希望通过练习加深理解的学生。 ### 第一部分:课后习题分析 #### 习题示例 ```java public ...
在IT领域,特别是软件开发与项目构建过程中,`Property`设置是极其常见且重要的操作。本文将深入探讨“Property设置属性的7种方法”,旨在帮助开发者理解和掌握多种灵活的属性配置方式,从而提升项目的可配置性和...
标题中的链接指向了一篇关于Acegi安全框架在Spring框架中使用的文章,而描述中的博文链接则是另一篇关于技术讨论的文章。结合标签“源码”和“工具”,我们可以推测这篇文章主要探讨的是如何通过Acegi安全框架来增强...
最近在搞在地图上画出路线图,经过一段时间的摸索,终于搞明白了,其实也挺简单的,写个类继承Overlay,并重写draw方法,在draw方法中画出 path即可。对于Overaly,在地图上标记某个点或者画线之类的就要使用overlay...
把它映射成表的形式, Search 是我要用到的查询bean SerachAction Struts的Action类 <br> <br> msn:ediku@263.net qq:50143539 我的博客:http://www.blogjava.net/ediku<br>希望和大家交个朋友一起...
在"浔阳江上 - BlogJava.htm"和"MyEclipse6_5上基于JAX-WS开发Webservice(中文示例) - 浔阳江上 - BlogJava_files"这两个文件中,可能包含了作者在BlogJava网站上分享的具体步骤和示例代码,帮助读者更好地理解和...