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 ...
随机推荐
- js数组去重(多种方法)
// js数组去重 Array.prototype.fun1 = function(){ var arr = this, result = [], i, len = arr.length; for(i ...
- JSON Web Tokens介绍
转载请标明出处: http://blog.csdn.net/forezp/article/details/72804324 本文出自方志朋的博客 ##什么是JWT 这篇文章选择性翻译于https:// ...
- Oracle oerr工具介绍
(1)什么是oerr oerr是Oracle提供的在UNIX/Linux上查看Oracle错误的小工具,使用起来非常方便. (2)如何使用 oerr工具位于ORACLE_HOME下面,可以使用whic ...
- 一位90后程序员的自述:如何从年薪3w到30w
▌自我介绍 引用赵真老师的一首歌<过去不是错>中的一句话:过去不是过错,毕竟我们也开心过.过去不是过错,何必愧疚不知所措. 我们这一代人,我相信多少都会有人和我一样,坚持过一个游戏,叫 D ...
- SQL、T-SQL与PL-SQL的区别
SQL.T-SQL与PL-SQL的区别 SQL是Structrued Query Language的缩写,即结构化查询语言.它是负责与ANSI(美国国家标准学会)维护的数据库交互的标准.作为关系数据库 ...
- Webpack Tapable原理详解
directory - src - sim ---- 简单的模拟实现 - /.js$/ ---- 使用 代码已上传github, 地址 Detailed Webpack 就像一条生产线, 要经过一系列 ...
- js分割字符串
js分割字符串 我想达到通过 : 分割 只要第一次分割,后面的内容不使用分割 不行,没找到可以直接用的方法,不过可以通过其它方式达到效果 eg: str.split(':',2)[0] (第一个分隔符 ...
- over开窗函数的用法
over(partition by c1.pmid,d1.type,e1.objid order by e1.objid ) pinum 先根据字段排序,pinum.在取第一条数据and p1.pi ...
- nginx配置SSL证书/强制跳转与非强制跳转
支持强制跳转HTTPS server { listen 80; server_name www.test.com; rewrite ^(.*)$ https://${server_name}$1 pe ...
- python文件操作(2017-8-5)
一.打开文件 open(文件名,模式,编码)#默认模式为只读 f = open("c:/asd.txt") date = f.read() f.close() print(date ...