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 ...
随机推荐
- GoBelieve Android SDK接入备忘
Android SDK版本 目前SDK只支持Android 2.2或以上版本的手机系统. AndroidManifest.xml配置 以下配置可以在IMDemo/AndroidManifest.xml ...
- oracle 完整性约束的禁用启用以及对表的影响,表的修改和复制
primary key ----表的唯一性约束,不能为空,且不能有重复值 foreign key ----俩表之间的约束,启用之时,在删除数据时需要先删除父表数据,再删除子表数据 禁用方式为:alte ...
- 关于SQLNET.AUTHENTICATION_SERVICES= (NTS) 的解释
原文转自:http://www.360doc.com/content/12/0207/12/3446769_184740592.shtml 标题所代表的意思为 使用操作系统本地验证,一般不 ...
- 【C语言】素数判定
题目:素数判定. 编写函数,参数是一个正整数n,如果它是素数,返回1,否则返回0. 分析 质数概念: 质数:除了1之外,只能被它本身整除的正数称为质数 如果这个数能被其他正数整除,说明这个数有两个或以 ...
- HTTP头部信息解释分析
HTTP 头部解释 1. Accept:告诉WEB服务器自己接受什么介质类型,*/* 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type. 2. Accept-Chars ...
- Python实现trim函数
Python中其实也有类似Java的trim函数的,叫做strip,举例: #!/usr/bin/python # -*- coding: UTF-8 -*- str = "0000000h ...
- vue.js 组件-全局组件和局部组件
这两天学习了Vue.js 感觉组件这个地方知识点挺多的,而且很重要,所以,今天添加一点小笔记. 首先Vue组件的使用有3个步骤,创建组件构造器,注册组件,使用组件3个方面. 代码演示如下: <! ...
- 使用deque保留有限的记录
# 使用deque保留有限的记录 >>> from collections import deque >>> q = deque(maxlen=3) # 指定队列的 ...
- laravel 中出现SQLSTATE[HY000] [2002] 如何解决?
在日常开发中总是难免遇到各式各样的错误,还有许多错误常常是重复出现的 以下是报错信息! SQLSTATE[HY000] [2002] ������ӷ���һ��ʱ���û���ȷ�
- C# 设置程序最小化到任务栏右下角,鼠标左键单击还原,右键提示关闭程序
首先设置程序最小化到任务栏右下角 先给窗口添加一个notifyIcon控件 为notifyIcon控件设置ICO图标(不设置图标将无法在任务栏显示) 给notifyIcon控件添加点击事件 然后是最小 ...