我们参考下面这个例子:

读者可以提前考虑一下,这段程序的输出会是什么。

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 多态方法构造器执行方法的更多相关文章

  1. Java 多态 父类和子类方法的访问控制权限

    Java 多态 父类和子类方法的访问控制权限 @author ixenos 父类和子类方法的访问控制权限 继承是为了扩展类的功能,而这种扩展显然就是对一个原始类的扩展,目的还是向上转型来调用,所以这就 ...

  2. 要想学好Java编程,构造器、方法重载、this关键字、垃圾回收机制,这4关一定要过!

    有人说,你应该关注时事.财经,甚至流行的电影.电视剧,才有可能趁着热点写出爆文:有人说,你别再写“无聊”的技术文了,因为程序员的圈子真的很小,即便是像鸿洋那样的招牌大牛,文章是那么的干货,浏览量有多少 ...

  3. Java基础03 构造器与方法重载

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在方法与数据成员中,我们提到,Java中的对象在创建的时候会初始化(initial ...

  4. Java基础03 构造器与方法重载(转载)

    显式初始化要求我们在写程序时就确定初始值,这有时很不方便.我们可以使用构造器(constructor)来初始化对象.构造器可以初始化数据成员,还可以规定特定的操作.这些操作会在创建对象时自动执行. 定 ...

  5. java 多态 ---父类调用子类方法

    package test1;//多态的体现import javax.print.attribute.standard.RequestingUserName;import java.util.Scann ...

  6. JAVA多线程间隔时间段执行方法

    import java.util.Date; import java.util.Timer; import java.util.TimerTask; public class ManyProject ...

  7. java反射获取类的类名、属性名、属性类型、方法、执行方法、构造函数

    public class Demo02 { @SuppressWarnings("all") public static void main(String[] args) thro ...

  8. 用arthas的watch方法观察执行方法的输入输出

    watch 的参数比较多,主要是因为它能在 4 个不同的场景观察对象 参数名称 参数说明 class-pattern 类名表达式匹配 method-pattern 方法名表达式匹配 express 观 ...

  9. Java反射、动态加载(将java类名、方法、方法参数当做参数传递,执行方法)

    需求:将java类名.方法.方法参数当做参数传递,执行方法.可以用java的动态加载实现   反射的过程如下:     第一步:通过反射找到类并创建实例(classname为要实例化的类名,由pack ...

随机推荐

  1. Java 基础总结

    Java基础总结 jdk:Java的开发环境与部署环境jre:Java的运行环境 Java数据类型分为:基本类型和引用类型 基本类型:①整数类型 byte   short   int   long 默 ...

  2. Unity 游戏框架搭建 (十二) 简易AssetBundle打包工具(二)

    上篇文章中实现了基本的打包功能,在这篇我们来解决不同平台打AB包的问题. 本篇文章的核心api还是: BuildPipeline.BuildAssetBundles (outPath, 0, Edit ...

  3. 第一次接触mysql

    一:数据库的好处 1. 可以持久化保存数据在本地 2.结构化查询 二:数据库常见的概念 1.DB: 是datebase数据库的缩写,储存数据得到容器 2.DBMS:数据库管理系统,用于管理数据库,和创 ...

  4. 20181009noip HZ EZ两校联考sum(莫队,组合数学)

    题面戳这里 思路: noip考莫队???!!! 考场上死活没往这方面想啊!!!数据分治忘写endl50pts滚粗了 这里每个询问都有n,m两个参数 我们可以把它看做常规莫队中的l和r 然后利用组合数的 ...

  5. WebMagic 启动例子报错

    报错内容: Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/conn/Http ...

  6. django环境搭建和学习

    由于服务器down了好几天,前几天做的django的project全都在上面,无法继续开展工作,所以决定在本地重新部署一套virtualenv 之前没有好好整理过部署过程(其实也不难),所以决定写个随 ...

  7. 【vlan之四种方式链路认证组网]

    ---恢复内容开始--- 根据项目需求,搭建好如下拓扑图: 在[sysname]下配置给予协议的vlan vlan 1#vlan 10 protocol-vlan 0 ipv4#vlan 20 pro ...

  8. php-5.6.26源代码 - hash存储结构 - 初始化

    初始化 有指定析构函数,在销毁hash的时候会调用,如:“类似extension=test.so扩展”也是存放在HashTable中的,“类似extension=test.so扩展”的module_s ...

  9. SQL命令(三)

    数据完整性约束 1)数据完整性约束包含:实体完整性.参照完整性.用户定义完整性. CREATE TABLE table( id INT NOT NULL AUTO_INCREMENT PRIMARY ...

  10. mysql日志管理#二进制日志详解

    查看MySQL二进制文件中的内容有两种方式 mysqlbinlog SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row ...