原帖地址:http://justt0.iteye.com/admin/blogs/1983634/edit
package com.p1; public class Father { void test(){ this.go();//即go(); } void go(){ System.out.println("father go"); } } package com.p1; public class Son extends Father { @Override void test() { // TODO Auto-generated method stub //指定super.test(); super.test(); //指定super.go(); super.go(); } @Override void go() { // TODO Auto-generated method stub System.out.println("son go"); } public static void main(String[] args) { Father f = new Son(); f.test(); } }
提到多态,首先要清楚创建子类的时候都发生了什么.(变量初始化总是在构造方法之前,我们在这里忽略它)我们知道执行new Son();后,由于继承关系,所以会先初始化父类---即会先创建一个父类对象(基对象这个对象是真实存在的,它和直接创建基类对象的区别是,前者的对象是包装在导出类的内部,后者则是外部),然后才是初始化子类--即创建子类对象,最后的结果是导出类对象(Son对象)的内部包装了一个基类对象(Father对象).
我们再说创建对象的方式,Father f = new Son();这是将一个Son对象付给了一个Father引用,事实上f就是一个Son对象,但是这个f只能访问基类对象子类对象都有的方法,然后执行f.test();方法,因为f指向的对象其实还是一个Son对象,所以调用的test方法就是son对象的test方法.
然后我们再说关键字this和super,有了上面的分析,我们可以将this认为是指向导出类对象,super指向的则是积累对象,有了这个思路,理解多态就容易多了.基类有两个方法,test()和go(),test调用go,在子类中我们覆盖这两个方法,父类的go()方法打印的是"father go",而子类的go()方法打印的是"son go",好了,go方法就这样,再说调用go方法的test方法,我们假设两种情况:
情况一:子类的test方法里面调用父类的test方法,即super.test();看到这个super了吧,它指的就是基类对象,好了,这样我们直接找到基类的test方法,它调用的是go();,这个go();我们也可以写成this.go();(这个都清楚吧,两种写法一个意思),好了,this出现了,这个this指的就是子类对象,那我们直接就找子类的go()方法,所以打印的是"son go",怎么样?容易吧?
情况二:子类的test方法里面直接调用父类的go方法,即super.go();看到super了吧,它指的是基类对象,这样我们直接找到父类的go()方法,所以打印的是"father go",即使子类有覆盖go()方法,没用.
说到这里,有朋友可能会想到,如果子类没有覆盖父类的go方法,子类只是覆盖基类的test方法呢? 这其实又是两种情况,理解方法也很简单:
情况一:如果子类的test方法执行的是super.test(),由于父类的test方法调用的是go()(即this.go();),这个this代指子类对象,但是子类对象并没有自己的go()方法,怎么办? 其实我们可以把它看成是一层一层的,如果子类没有go方法,那么它就会向里面找,所以就会找到父类的go()方法,所以就会打印出"father go"的结果.
情况二:如果子类的test方法执行的是super.go(),直接找到父对象的go方法,没说的,打印的是"father go".
可能有人又会想到,如果子类什么都没覆盖,只是继承了父类呢? 这其实又是一种情况,f.test();调用子类的test()方法,由于子类没有明确覆盖test方法,所以,向里找,在基类找到了test方法,然后test方法里调用了this.go();方法,this代指Son对象,在Son对象里又没找到明确覆盖的go()方法,所以又向里找,所以找到了基类对象的go()方法,所以打印的是father go.
[2013.12.03]更新
今天看到IBM官网上的一篇文章,http://www.ibm.com/developerworks/cn/java/j-lo-polymorph/,印证了我的理解,首先,this指的就是实际的对象,不管引用对象的引用是什么,对象的类型是不变的,比如,Father f = new Son();即使引用Son对象的是Father的引用,但如果你试一下将f打印出来,然后再将f向上转型为son,然后将转型后对象打印出来,你就会发现两者打出来的结果是一致的,就是com.p1.Son@142c63f,为什么呢? 看下源码就会发现,如果system.out.println();打印一个object的话,调用的是该object的toString方法,源码是这样的:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
意思是类的名字+@+对象的hashcode的16进制字符串表现形式,hashcode大家都知道,是唯一的,再看上面的结果com.p1.Son@142c63f,首先,即使是Father引用指向的他,但他还是一个Son对象,再看hashcode部分,转型前后@后面的都一样,说明,对象还是那个对象,没有产生新对象.
接着,我们回到主题,http://www.ibm.com/developerworks/cn/java/j-lo-polymorph/,这篇文章有一幅描绘方法表的图:
大概意思是,girl和boy都继承自object,我们拿girl来说,首先,girl复写了object的toString()方法,然后,girl又多了两个方法,eat()和speak(),对于一个girl对象来说如果调用girl的eat()方法,哪个箭头(我们把他看做指针),就会直接指向girl的eat();如果调用的是toStirng();方法,但是object有同名方法,怎么办? 答案是,指针会直接指向girl里面的toString();方法,而忽略掉object里面toStirng方法,这其实就是多态的实现,很清晰的思路,再说如果调用没有被girl复写的object方法,指针会直接指向object的方法代码,也很简单.
至于变量的覆盖,可以参照这篇文章,http://developer.51cto.com/art/201204/327772.htm和这篇文章http://blog.csdn.net/tryandlearn/article/details/8742367
相关推荐
java多态、继承练习题,包含题目与答案,............................................................................................................
Java多态是面向对象编程中的一个核心概念,它在Java编程中扮演着至关重要的角色。多态性(Polymorphism)一词源自希腊语,意为“多种形态”,在计算机科学中,它允许我们使用一个接口来表示多种类型的数据,从而实现...
计算机后端-PHP视频教程. php之面向对象29 多态(选学).wmv
对 Java 中多态理解 Java 中的多态是指在不同的情况下可以有不同的行为,多态是面向对象编程的一种基本特征。多态的实现是通过方法重载和方法重写来实现的。 在 Java 中,多态可以分为两种:编译时多态和运行时...
Java多态理解 java中的多态性是面向对象编程的精髓所在。多态性是指父类引用指向子类对象,例如父类Animal,子类Cat和Dog。其中Animal可以是类也可以是接口,Cat和Dog是继承或实现Animal的子类。Animal animal = ...
C++开发基于多态的公司职工管理系统(课设源码).zipC++开发基于多态的公司职工管理系统(课设源码).zipC++开发基于多态的公司职工管理系统(课设源码).zipC++开发基于多态的公司职工管理系统(课设源码).zipC++开发基于...
### 继承与多态知识点解析 #### 一、继承的特点及应用场景 **定义与特点:** 继承是一种面向对象编程的基本特性,它允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)的属性和方法。通过继承,可以...
Python工具箱.zip - 办公自动化、多态文件搜索、高级加密。Python工具箱.zip - 办公自动化、多态文件搜索、高级加密。Python工具箱.zip - 办公自动化、多态文件搜索、高级加密。Python工具箱.zip - 办公自动化、多态...
在这个“java多态实验”中,我们可以看到一系列小代码实例,这些实例旨在帮助理解和应用多态特性。下面我们将深入探讨多态的概念、实现方式以及它在实际开发中的应用。 1. 多态性定义: 多态(Polymorphism)源自...
### 理解Java中的多态 首先,Java中的多态是通过方法重载(Overloading)和方法重写(Overriding)实现的。方法重载发生在同一个类中,而方法重写发生在子类和父类之间。 #### 方法重写(方法覆盖) 在上述代码中...
Java多态是面向对象编程中的一个核心概念,它允许我们使用父类引用处理子类对象,从而实现更灵活的代码设计。在这个“Java多态案例及源码.rar”压缩包中,你将找到一系列关于Java多态的实例和源代码,非常适合教师在...
在Java编程语言中,多态(Polymorphism)是一种核心特性,它允许我们设计更加灵活、可扩展的代码。多态使得一个接口可以有多种不同的实现或者表现形式,...理解和熟练运用多态,对于编写高质量的Java应用程序至关重要。
通过理解并熟练运用上述Java多态的概念,开发者可以编写出更加灵活、可扩展的代码,提升软件系统的整体质量和性能。在实际项目中,多态性常用于构建模块化的系统,使组件之间能以一种松散耦合的方式交互,实现高效的...
Java多态是面向对象编程的核心特性之一,它允许我们使用一个通用的接口来处理不同类型的对象,从而实现代码的灵活性和可扩展性。在Java中,多态主要通过三种方式实现:继承、接口和方法的重写。 1. **继承与多态**...
在这个"Java_ploymorphism.rar"压缩包中,包含的四个Java源文件——ArrayListTest.java、ObjectVarTest.java、ObjectTypeTest.java和BasicTypeTest.java,很可能是用来演示和练习Java多态性的不同应用场景。...
Java的多态性是面向对象编程的一个核心特性,它允许我们使用一个接口来表示不同的类,使得代码更加灵活,易于维护。多态性是通过继承、接口和方法重写来...理解并熟练运用多态,能帮助开发者编写出更高质量的Java程序。
Java多态是面向对象编程中的一个核心概念,它允许我们以一种统一的方式处理不同类型的对象。在Java中,多态性主要体现在方法的重写(Override)和重载(Overload)。通过多态,我们可以编写出更加灵活、可扩展的代码...
在Java编程语言中,继承、抽象和多态是面向...通过理解并熟练运用继承、抽象和多态,开发者可以构建出更加灵活、高效且易于扩展的Java应用程序。在实际开发中,这三个概念常常结合使用,以实现复杂的功能和业务逻辑。
Java多态的实现机制 Java 多态的实现机制是面向对象程序设计中代码重用的一个重要机制。多态性是 Java 的三大属性之一,在开发中很重要的一个环节。多态性使对象能够调用正确的方法版本,从而提高代码的重用性和...