`

java 之多态(转)

    博客分类:
  • java
阅读更多

 转自:http://skyuck.iteye.com/blog/870217

 

关于java多态之前也写过一篇文章 
java多态之父子构造器 

今天看了java编程思想多态那章节,觉得还是有几个地方需要做一个记录 
1.多态与域 
    当我了解多态机制的时候,我认为所有的事物都可以多态的发生,然而事实上之后普通的方法调用才是多态的,例如,如果你直接访问某个域,这个访问就将在编译器就进行解析,而不是通过动态绑定进行的。 

Java代码  收藏代码
  1. package com.unis.ploy.music;  
  2.   
  3. public class FieldAccess {  
  4.   
  5.     /** 
  6.      * @param args 
  7.      */  
  8.     public static void main(String[] args) {  
  9.           
  10.         Super sub = new Sub();  
  11.         System.out.println("sub.field="+sub.field+"  ,sub.getField()="+sub.getField());  
  12.           
  13.         Sub sub1 = new Sub();  
  14.         System.out.println("sub1.field="+sub1.field+"  ,sub1.getField()="+sub1.getField()+"  ,sub1.getSuperField()="+sub1.getSuperField());  
  15.     }  
  16. }  
  17.   
  18. class Super{  
  19.     public int field=0;  
  20.       
  21.     public int getField(){  
  22.         return field;  
  23.     }  
  24. }  
  25.   
  26. class Sub extends Super{  
  27.       
  28.     public int field = 1;  
  29.       
  30.     public int getField(){  
  31.         return field;  
  32.     }  
  33.       
  34.     public int getSuperField(){  
  35.         return super.field;  
  36.     }  
  37. }  



我们可以看到上面的代码的运行结果如下: 

引用

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.构造器内部的多态方法的行为 
我们知道构造器调用的层次机构,先调用基类的构造器,再调用导出类的构造器,这样就会带来一个有趣的两难问题。 
如果在一个基类的构造器的内部调用正在构造的对象(这个对象还没有被构造出来)的某个动态绑定方法,将会出现什么情况呢。 

例如下面的例子 

Java代码  收藏代码
  1. package com.unis.ploy.music;  
  2.   
  3. class Glyph{  
  4.     void draw(){  
  5.         System.out.println("Glyph.draw()");  
  6.     }  
  7.     public Glyph() {  
  8.         System.out.println("Glyph() before draw()");  
  9.         draw();  
  10.         System.out.println("Glyph() after draw()");  
  11.     }  
  12. }  
  13.   
  14. class RtGlyph extends Glyph{  
  15.       
  16.     private int radius = 1;  
  17.       
  18.     public RtGlyph(int r) {  
  19.         radius = r;  
  20.         System.out.println("RgGlyph.RtGlyph(),radius="+radius);  
  21.     }  
  22.       
  23.     void draw(){  
  24.         System.out.println("RgGlyph.draw(),radius="+radius);  
  25.     }  
  26. }  
  27.   
  28.   
  29. public class RoundGlyph extends Glyph{  
  30.       
  31.     public static void main(String[] args) {  
  32.         new RtGlyph(5);  
  33.     }  
  34.   
  35. }  


让我们看一下控制台输出信息 

引用

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多态中的类型转换,包括向上转型(Upcasting)和向下转型(Downcasting),以及相关的注意事项。 1. **向上转型(Upcasting)** 向上转型是指将子类的对象引用赋值给父类的引用。在Java中,这是...

    java中多态的内存分析

    多态性分为编译时多态和运行时多态,其中运行时多态是Java中最常见的形式,也称为动态绑定。在深入探讨Java中多态的内存分析之前,我们需要先理解一些基本概念。 首先,了解Java内存模型至关重要。Java程序运行时...

    北大青鸟javaOOP多态Ch03作业全集.rar

    "北大青鸟javaOOP多态Ch03作业全集.rar"这个压缩包文件很显然是针对学习者提供的一系列关于Java多态性的练习和案例,帮助学生深入理解并掌握这一核心技能。 多态性是面向对象三大特性之一,另外两个是封装和继承。...

    java多态练习题

    java多态、继承练习题,包含题目与答案,............................................................................................................

    Java多态的讲解

    Java多态的讲解

    java中多态实现

    java多态实现的课件,给那些需要的人 讲述了java多态的概念、分类、实现 综合案例讲解、总结多态的作用

    java多态的总结

    在Java中,多态分为编译时多态和运行时多态。编译时多态主要体现在方法的重载(Overloading),即在同一个类中可以有多个同名方法,但参数列表不同。编译器会根据传入参数的类型和数量来决定调用哪个方法。运行时...

    Java基础之多态ppt

    Java基础之多态课程PPT适用于基础学习者使用,很好的课程资源

    对java中多态理解

    对 Java 中多态理解 Java 中的多态是指在不同的情况下可以有不同的行为,多态是面向对象编程的一种基本特征。多态的实现是通过方法重载和方法重写来实现的。 在 Java 中,多态可以分为两种:编译时多态和运行时...

    10-JAVA-多态

    JAVA多态思维导图,便捷整理思路,多态的好处、多态的语法格式、多态中的两种类型转换:向上转型、向下转型

    深入Java核心 Java中多态的实现机制编程资料

    ### 深入Java核心:Java中多态的实现机制 多态性是面向对象编程中的一个重要概念,它使得程序代码具有高度的灵活性和可扩展性。...多态是Java面向对象编程的核心概念之一,掌握好它对于编写高质量的Java程序至关重要。

    java 多态 经典讲解

    ### Java多态经典讲解 #### 一、理解Java多态 多态,作为面向对象编程的三大特性之一,是继抽象和继承之后的关键概念。它允许我们以统一的接口处理不同类型的对象,增强了代码的灵活性和可扩展性。在Java中,多态...

    java的多态扩展性

    java教学视频,讲解了多态的扩展性、转型、成员特点、主板实例、object类等

    Java基础多态PPT教学课件.pptx

    Java基础多态PPT教学课件.pptx

    java继承和多态ppt

    java 继承和多态PPT教程

    Java的多态.md

    Java的多态是学习Java的第一个重点,也是一个难点。在学习Java多态之前, 要学好封装和继承,封装和继承是理解多态的一个过程。在表现多态时,同 时也体现了封装和继承。

    Java中多态的具体应用代码

    在Java编程语言中,多态性(Polymorphism)是面向对象编程的三大特性之一,另外两个是封装和继承。多态性允许我们使用一个接口来代表多种类型的对象,这使得代码更加灵活、可扩展且易于维护。在这个主题中,我们将...

    java基础-java多态详解

    Java 多态详解 Java 多态是 Java 编程语言中的一种基本概念,它允许开发者定义一个接口,并且可以通过不同的类来实现该接口。多态性是 Java 面向对象编程的核心机制之一,它使得程序更加灵活、可维护和可扩展。 ...

    java 多态.docx

    总结来说,Java中的多态是通过继承、重写和父类引用子类对象来实现的,它提供了代码的灵活性、可扩展性和可维护性,是面向对象编程的重要特征之一。理解和熟练运用多态,对于编写高质量的Java应用程序至关重要。

    JAVA多态图文详解ppt

    JAVA多态图文详解ppt,详细通过各种举例介绍JAVA多态的ppt

Global site tag (gtag.js) - Google Analytics