转自:http://skyuck.iteye.com/blog/870217
关于java多态之前也写过一篇文章
java多态之父子构造器
今天看了java编程思想多态那章节,觉得还是有几个地方需要做一个记录
1.多态与域
当我了解多态机制的时候,我认为所有的事物都可以多态的发生,然而事实上之后普通的方法调用才是多态的,例如,如果你直接访问某个域,这个访问就将在编译器就进行解析,而不是通过动态绑定进行的。
- package com.unis.ploy.music;
- public class FieldAccess {
- /**
- * @param args
- */
- public static void main(String[] args) {
- Super sub = new Sub();
- System.out.println("sub.field="+sub.field+" ,sub.getField()="+sub.getField());
- Sub sub1 = new Sub();
- System.out.println("sub1.field="+sub1.field+" ,sub1.getField()="+sub1.getField()+" ,sub1.getSuperField()="+sub1.getSuperField());
- }
- }
- class Super{
- public int field=0;
- public int getField(){
- return field;
- }
- }
- class Sub extends Super{
- public int field = 1;
- public int getField(){
- return field;
- }
- public int getSuperField(){
- return super.field;
- }
- }
我们可以看到上面的代码的运行结果如下:
sub.field=0 ,sub.getField()=1
sub1.field=1 ,sub1.getField()=1 ,sub1.getSuperField()=0
当Sub对象转型为Super引用时,任何域访问操作都将由编译器解析,因此域的操作不是多态的,在本例中,为Super.field和Sub.field分配了不同的存储空间。这样,Sub实际上包含两个称为field的域:它自己的和从Super处得到的。然而,在引用Sub中的field时所产生的默认域并非Super的field域,因此,为了得到Super.field,必须显式的指明super.field.
2.构造器和多态
编程思想:构造器并不具有多态性(它们实际上是static方法,只不过该static申明是隐式的)
在上篇文章中我们知道基类的构造器总是在导出类的构造过程中被调用。其实这样做是有意义的,因为构造器具有一项特殊的任务,检查对象是否被正确构造。导出类只能访问它自己的成员,不能访问基类中的成员,只有基类的构造器才能对自己的元素进行初始化,因此在一个继承的类层次结构中构造器的调用顺序为:
- 调用基类的构造器,这个步骤会不断的反复递归下去,首先是构造层次的根,然后是下一层导出类,等等,直到最底层的导出类
- 按声明顺序调用成员的初始化方法
- 调用导出类构造器的主体
3.构造器内部的多态方法的行为
我们知道构造器调用的层次机构,先调用基类的构造器,再调用导出类的构造器,这样就会带来一个有趣的两难问题。
如果在一个基类的构造器的内部调用正在构造的对象(这个对象还没有被构造出来)的某个动态绑定方法,将会出现什么情况呢。
例如下面的例子
- package com.unis.ploy.music;
- class Glyph{
- void draw(){
- System.out.println("Glyph.draw()");
- }
- public Glyph() {
- System.out.println("Glyph() before draw()");
- draw();
- System.out.println("Glyph() after draw()");
- }
- }
- class RtGlyph extends Glyph{
- private int radius = 1;
- public RtGlyph(int r) {
- radius = r;
- System.out.println("RgGlyph.RtGlyph(),radius="+radius);
- }
- void draw(){
- System.out.println("RgGlyph.draw(),radius="+radius);
- }
- }
- public class RoundGlyph extends Glyph{
- public static void main(String[] args) {
- new RtGlyph(5);
- }
- }
让我们看一下控制台输出信息
Glyph() before draw()
RgGlyph.draw(),radius=0
Glyph() after draw()
RgGlyph.RtGlyph(),radius=5
第一次radius的输出信息为0,而不是1。
让我们来分析出现这种情况的原因吧,当执行new RtGlyph(5)时,我们知道先会执行基类的构造器,也就是说会先执行Glyph()构造方法,在Glyph()构造方法里面又调用了一个动态绑定的方法,我们都知道对于一个动态绑定的方法,会先从导出类中去找,如果导出类覆盖了基类的方法,就会调用导出类中的方法,这个时候也就是会调用导出类RtGlyph的draw()方法,可以这个时候导出类RtGlyph还没有被构造,因此类中的成员radius还没有被分配内存,因此第一次就输出radius=0。
相关推荐
Java 多态中的类型转换
java多态、继承练习题,包含题目与答案,............................................................................................................
代码演示对java中多态的理解 从代码演示中更好的理解多态的作用
Java多态的讲解
java的多态,是一个很重要的环节.但是要知道什么是多态!
java多态实现的课件,给那些需要的人 讲述了java多态的概念、分类、实现 综合案例讲解、总结多态的作用
深入Java核心 Java中多态的实现机制
Java基础之多态课程PPT适用于基础学习者使用,很好的课程资源
JAVA多态思维导图,便捷整理思路,多态的好处、多态的语法格式、多态中的两种类型转换:向上转型、向下转型
想要下载此文件,请先下载本人“java程序中的内存分配问题”,因为那个例子比较简单而且分析详细透彻,可以使你更容易理解,如果你对java程序执行过程中的内存分配有一定的了解,可以直接下载本文件
Java开发之多态的具体应用,包含多态应用的实例和相应实例的代码。
北大青鸟javaOOP多态Ch03作业全集.rar
java教学视频,讲解了多态的扩展性、转型、成员特点、主板实例、object类等
利用大量代码讲解java的多态,让你更容易理解和应用。
Java基础多态PPT教学课件.pptx
java 继承和多态PPT教程
java多态的基础知识,你可能了解,但是如何使用?内附例子。究竟如何实现,帮你学习基础。
Java的多态是学习Java的第一个重点,也是一个难点。在学习Java多态之前, 要学好封装和继承,封装和继承是理解多态的一个过程。在表现多态时,同 时也体现了封装和继承。
JAVA多态图文详解ppt,详细通过各种举例介绍JAVA多态的ppt
Java 继承 多态方面的实例源码,内容方面涉及对象类Object和它的toString()方法、多态性、动态绑定和一般程序设计、数组线性表ArrayList类、final类、方法和变量、数据域和静态方法的隐藏等。。。