Java 多态方法构造器执行方法
我们参考下面这个例子:
读者可以提前考虑一下,这段程序的输出会是什么。
public class Polymorphism {
/**
* 创建一个类A
* 该类中有一个方法draw,以及一个构造方法A
*/
static class A{
void draw(){
System.out.println("A.draw()");
}
A(){
System.out.println("A() before draw()");
draw();
System.out.println("A() after draw()");
}
}
/**
* 创建一个类B,继承A
* 该类中同样有一个方法draw,以及一个构造方法B
*/
static class B extends A {
private int value=1;
void draw(){
System.out.println("B.draw(),value="+value);
}
B(int v){
value=v;
System.out.println("B.B(),value="+value);
}
}
/*现在我们调用B的构造函数,构造一个B*/
public static void main(String[] args) {
new B(5);
}
}
最后的输出结果为
A() before draw()
B.draw(),value=0
A() after draw()
B.B(),value=5
初次分析
可见,当我们试图构造一个B时,应该会优先构造B的父类A,所以会调用父类A的构造函数A(),所以会输出
A() before draw()
这时A调用了draw()方法,因为是构造B类,而B类覆盖重写A类的draw()方法,所以这里应该调用的是B类重写过后的draw()方法,而B类的value默认值为1,所以会输出
B.draw(),value=1
A() after draw()
此刻父类A已经完成构造,所以接着才会构造B,调用B的构造函数B(),且传入的值为5,所以会输出
B.B(),value=5
而实际上,最后输出的并不是
B.draw(),value=1
而是
B.draw(),value=0
最后在《Thinking in Java》一书中找到了类似的例子,其中给出了一套正确的初始化顺序:
(1)在其他任何事物之前,将分配给对象的存储空间初始化为二进制的零;
(2)如前所述那样调用基类构造器。此时,调用被覆盖后的draw()方法 (要在调用B构造器之前调用),由于步骤1的缘故,我们此时会发现value的值为0。
(3)按照声明的顺序调用成员的初始化方法。
(4)调用导出类的构造器主体。
Java 多态方法构造器执行方法的更多相关文章
- Java 多态 父类和子类方法的访问控制权限
Java 多态 父类和子类方法的访问控制权限 @author ixenos 父类和子类方法的访问控制权限 继承是为了扩展类的功能,而这种扩展显然就是对一个原始类的扩展,目的还是向上转型来调用,所以这就 ...
- 要想学好Java编程,构造器、方法重载、this关键字、垃圾回收机制,这4关一定要过!
有人说,你应该关注时事.财经,甚至流行的电影.电视剧,才有可能趁着热点写出爆文:有人说,你别再写“无聊”的技术文了,因为程序员的圈子真的很小,即便是像鸿洋那样的招牌大牛,文章是那么的干货,浏览量有多少 ...
- Java基础03 构造器与方法重载
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在方法与数据成员中,我们提到,Java中的对象在创建的时候会初始化(initial ...
- Java基础03 构造器与方法重载(转载)
显式初始化要求我们在写程序时就确定初始值,这有时很不方便.我们可以使用构造器(constructor)来初始化对象.构造器可以初始化数据成员,还可以规定特定的操作.这些操作会在创建对象时自动执行. 定 ...
- java 多态 ---父类调用子类方法
package test1;//多态的体现import javax.print.attribute.standard.RequestingUserName;import java.util.Scann ...
- JAVA多线程间隔时间段执行方法
import java.util.Date; import java.util.Timer; import java.util.TimerTask; public class ManyProject ...
- java反射获取类的类名、属性名、属性类型、方法、执行方法、构造函数
public class Demo02 { @SuppressWarnings("all") public static void main(String[] args) thro ...
- 用arthas的watch方法观察执行方法的输入输出
watch 的参数比较多,主要是因为它能在 4 个不同的场景观察对象 参数名称 参数说明 class-pattern 类名表达式匹配 method-pattern 方法名表达式匹配 express 观 ...
- Java反射、动态加载(将java类名、方法、方法参数当做参数传递,执行方法)
需求:将java类名.方法.方法参数当做参数传递,执行方法.可以用java的动态加载实现 反射的过程如下: 第一步:通过反射找到类并创建实例(classname为要实例化的类名,由pack ...
随机推荐
- Oracle数据库中游标的游标的使用
本人不喜欢说概念啥的,就直接说明使用方法吧 案例1: DECALRE --声明游标 CURSOR C_USER(C_ID NUMBER) IS SELECT NAME FROM USER WHERE ...
- ArrayList使用
package com.nrxt; import java.util.ArrayList; /** * 概述: * 功能: * 作者:郑肖亚 * 创建时间:2019/3/13 22:01 */ pub ...
- eclipse内存溢出解决
1 查看内存: workspace/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs,在里面加上SH ...
- js中判断数组中是否包含某元素的方法
方法一:array.indexOf(item,start):元素在数组中的位置,如果没与搜索到则返回 -1. 参数 描述 item 必须.查找的元素. start 可选的整数参数.规定在数组中开始检索 ...
- ABAP术语-Accounting Document
Accounting Document 原文:http://www.cnblogs.com/qiangsheng/archive/2007/12/12/991731.html Accounting d ...
- MySQL-5.7.20主从复制测试[20180110]
前言 MySQL 5.7.20测试主从复制 环境 主库 192.168.1.59 t-xi-sonar01 从库 192.168.1.51 t-xi-orc01 设 ...
- JAVAOOP多线程
进程每个独立运行的任务对应一个进程,每个进程可以产生多个线程 特点:1,进程是系统运行程序的基本单位 2,每一个进程都有自己独立的一块内存空间,一组系统资源 3,每一个进程的内部数据和状态都是完全独立 ...
- python3 练习题100例 (二十三)与7相关的数
与7相关的数:如果一个正整数,它能被7整除或者它的十进制表示法中某个位数上的数字为7,则称之为与7相关的数.(10分) 题目内容: 现在我们给定一个正整数n(n<1000),求所有小于等于n的与 ...
- Python学习:3.Python学习基础
Python基础概念 一.编码 Python解释器加载.py文件中的代码的时候,对内容进行编码,在Python2.x中默认使用的是ASCII,因此我们使用Python2.x版本输出中文的时候,会出现以 ...
- react-router 4.0中跳转失灵
在https://github.com/ReactTraining/history文档中,跳转是 用这种方法,但是,用了之后就存在这么一个问题,网址换了但是页面并没有刷新. 查了资料后,history ...