构造器的多态行为
来源:互联网 发布:java反序列化漏洞扫描 编辑:程序博客网 时间:2024/05/24 02:21
我们知道,在调用父类构造器时,得先要调用子类构造器。如果父类有方法f(),子类对其重写了,恰好父类构造器中用到了这个f()方法,那么这个f()调用的是父类中的f()还是子类中已经重写的f()呢?
不妨用一个例子试试看,这个例子引用自Thinking in java。
class Glyph {void draw() {System.out.println("Glyph.draw()");}Glyph() {draw();}}class RoundGlyph extends Glyph {private int radius = 1;public RoundGlyph(int r) {radius = r;System.out.println("RoundGlyph.RoundGlyph(),radius=" + radius);}void draw() {System.out.println("RoundGlyph.draw(), radius=" + radius);}}public class PolyConstructors {public static void main(String[] args) {new RoundGlyph(5);}}
RoundGlyph.draw(), radius=0
RoundGlyph.RoundGlyph(),radius=5
分析:
1.从结果中可以看到draw()调用的是子类中的draw()。这个可以这样理解:非静态非final方法是动态绑定的,方法调用者对象的实际类型来决定调用哪一个方法,这里是通过new RoundGlyph()(虽然此时还是一个未完全初始化的不完整对象)来最终能调用到draw()这个方法,所以应该是调用RoundGlyph中的draw()方法。
2.radius=0。 ???这是怎么回事???现在来解释这个问题。
之前的关于初始化顺序的文章中强调过,构造器的调用是在成员初始化完成之后的。但是这里,通过构造器执行draw()方法的时候,radius进行初始化了么?答案是没有。所以此时打印出的radius是在未赋值之前的默认值0。
关于初始化顺序再说的详细点儿,int radius = 1,这句话实际上给radius赋过两次值,第一次是默认值0,第二次是1。new RoundGlyph()一执行之后,先在堆中划出一片区域,所有的非静态成员都先初始位成了二进制的0,此时的radius是0。等到慢慢初始化,轮到radius了,才第二次赋值为1。所以会出现上面的结果。
因此,编写构造器有一条有效的准则" 用尽可能简单的方法使对象进入正常状态,如果可以的话,避免调用其他方法"。在构造器内唯一能够安全调用的是基类中的final方法,因为final方法不能被重写(private方法也属于final方法)。
- 构造器内部的多态行为
- 构造器的多态行为
- JAVA构造器内部的多态方法的行为
- 构造器内部的多态方法的行为
- 构造器内部的多态方法的行为
- Java构造器内部的多态方法的行为
- 构造器内部的多态方法的行为
- 构造器内部的多态方法的行为
- 构造器内部的多态方法的行为
- 构造器内部的多态方法的行为
- 构造器内部的多态方法的行为
- 构造器内部的多态方法行为
- java 构造器内部的多态方法和行为
- 构造器内部的多态方法行为
- Java知识点笔记--构造器内部的多态行为
- 构造器内部多态行为
- 主题:构造方法内部的多态方法的行为
- java,构造函数内部的多态行为
- #define用法总结
- 解决ubutun下vim编辑器不能正常使用的情况(添加软件源)
- MYSQL 数据库导入导出命令
- 国庆回家记之2017
- python中判断文件是否存在的三种方式
- 构造器的多态行为
- C语言中指向函数的指针
- Android OkHttp完全解析 是时候来了解OkHttp了
- 数据类型2
- org.apache.ibatis.binding.BindingException【原因汇总】
- Huffman编码树
- javaScript知识点整理(二)
- Construct 2添加背景音乐
- pandas学习笔记3—数据重塑图解Pivot, Pivot-Table, Stack and Unstack