下面是一个关于多态的示例,下面将主要针对这个例子进行分析:
package javaDemo.unit8; import java.io.ObjectInputStream.GetField; class Glyph{ int field1 = 1; static int field2 =2; public String getField(){ return "Glyph: field1 = " + field1 + ", field2 = " + field2; } void draw(){ System.out.println("Glyph.draw()"); } static void info(){ System.out.println("Glyph.static info()"); } Glyph(){ System.out.println("Glyph() before info()"); info(); System.out.println("Glyph() after info()"); System.out.println("Glyph() before draw()"); draw(); System.out.println("Glyph() after draw()"); } } class RoundGlyph extends Glyph{ int field1 = 3; static int field2 = 4; private int radius = 1; public String getField(){ return "RoundGlyph: field1 = " + field1 + ", filed2 = " + field2; } public String getSuperField(){ return "SuperFiled: field1 = " + super.field1 + ", filed2 = " + field2; } public RoundGlyph(int r) { radius = r; System.out.println("RoundGlyph.RoundGlyph(), radius = " + radius); } void draw(){ System.out.println("RoundGlyph.draw(), radius = " + radius); } static void info(){ System.out.println("RoundGlyph.info()"); } } public class PolyConstructors { public static void main(String[] args) { Glyph g = new RoundGlyph(7); g.draw(); g.info(); System.out.println("g.field1 = " + g.field1 + ", g.field2 = " + g.field2); System.out.println(g.getField()); } }
输出如下:
Glyph() before info()
Glyph.static info()
Glyph() after info()
Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 7
RoundGlyph.draw(), radius = 7
Glyph.static info()
g.field1 = 1, g.field2 = 2
RoundGlyph: field1 = 3, filed2 = 4
通过以前对多态学习,很容易分析出最下的输出:
①RoundGlyph: field1 = 3, filed2 = 4
这是由于Java中除了static方法和final方法(private方法也属于final方法)之外,其他所有的方法都是动态绑定的。
绑定:将一个方法调用同一个方法主体关联起来。
绑定分为:前期绑定和动态绑定(后期绑定,运行时绑定)
前期绑定:在程序执行前进行绑定
后期绑定:运行时根据对象的类型进行绑定。
而对于输出
②g.field1 = 1, g.field2 = 2
这是由于对于filed的访问操作,是由编译器进行解析的,不是多态的。所以输出直接为父类的field的值。
在实际的开发过程中,我们通常将filed设置为private,然后通过get方法获取到值,所以获取的为子类的field的值。这又一次提醒我们,不要为子类和基类中的field设置相同的名字。
③可以看出在进行初始化时,基类的构造器会首先被调用。
这是由于导出类一般只能访问自己的成员,不能访问基类的成员,只有基类的构造器能够适当的完成对自己元素的初始化。而且子类可以访问基类中的为public和protected成员,来完成子类的初始化,所以必须让所有的构造器都得到调用,才能构造出完整的对象,才能保证子类对象从所有直接或间接父类中继承的实例变量都被正确的初始化。
④
Glyph() before info()
Glyph.static info()
Glyph() after info()
info(),为static方法前期绑定,所以调用的为基类的方法。
⑤
Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 7
可以看出在子类初始化时,执行父类构造方法时,构造方法内的方法仍然为动态绑定。
我们来分析一下初始化的顺序:
1)最初,将分配给对象的存储空间初始化为二进制的零。
2)如果初始化的类存在父类,则调用父类的构造方法,构造方法内的方法调用遵循动态调用的规则(此时初始化类的构造方法还未被调用,所以radius的值为0)。
3)按照声明的顺序调用成员的初始化方法。
4)调用初始化类的构造方法。
这也提醒我们:我们应当使用尽可能简单的方法使对象进入正常的状态;尽量避免调用其他方法。在构造方法内能够安全调用的方法是基类的final方法(或private方法)。
相关推荐
Java基础之多态课程PPT适用于基础学习者使用,很好的课程资源
NULL 博文链接:https://zsl131.iteye.com/blog/626615
java多态的基础知识,你可能了解,但是如何使用?内附例子。究竟如何实现,帮你学习基础。
内含Java基础多态知识点笔记,及部分对应练习题。
非常好的Java基础视频,帮助你掌握Java基础知识 视频很清晰
Java基础多态PPT教学课件.pptx
java基础_继承封装 多态,概念的梳理,对初学者很有帮助,看一遍就清楚了
建议读者在阅读前具备Java的基础知识,包括类、对象、方法和继承等概念。 在阅读过程中,尝试编写简单的Java程序,体验多态的效果,并观察父类引用指向子类对象时的行为变化。 建议通过阅读相关的Java教材或搜索资料...
本PPT对java继承的基本概念,语法及应用进行了讲解。在继承的基础上进一步讲解了由继承引出的方法重写及上塑造性,最后引出多态的概念以及相关代码实例
//练习: //1.做一个教师类Teacher,有属性:1.教师号,2教师姓名, //3教师工资(基本工资,课时费,课时数)。 //有方法:1.输出教师所有信息,2.... //2....//(1)该类有以下属性:学校编号:schId, ...
Java基础多态PPT学习教案.pptx
java基础多态PPT教案学习.pptx
Java SE编程入门教程 java封装继承多态(共56页).pptx Java SE编程入门教程 java集合(共38页).pptx Java SE编程入门教程 java接口(共21页).pptx Java SE编程入门教程 java类和对象方法以及包的使用(共56页)....
Java基础入门教程 Java编程技术05 继承和多态(2学时)(共40页).ppt Java基础入门教程 Java编程技术06 类的高级特征(4学时)(共55页).ppt Java基础入门教程 Java编程技术07 异常(2学时)(共27页).ppt Java基础入门...
Java基础语法之接口和多态穿拖鞋的汉子上传
主要介绍了进一步理解Java中的多态概念,是Java入门学习中的基础知识,需要的朋友可以参考下
Java基础入门教程 第4章 继承和多态(共36页).ppt Java基础入门教程 第5章 Java基础类的应用(共42页).ppt Java基础入门教程 第6章 集合框架(共28页).ppt Java基础入门教程 第7章 Java中的异常处理(共26页)....
这个是本人辛苦整理的Java多态基本基础的知识点,以下就是很重要的东西,欢迎下载参考!
内容为本人学习java多态封装时整理的基础知识笔记,内容包括java中的多态和封装
JAVA面向对象基础测试题-继承-封装-多态等测试题.docx