其实我们发现子类继承父类操作很简单,如果要是去深入的研究下会发现,实例化过程并非是我们看到的那样,我们就以代码举例来说明;


问大家,以下代码执行会输出什么呢?

package com.oop;

/**
* 定义动物对象
* @author Liudeli
*
*/
class Animal { public Animal() {
System.out.println("Animal()--构造函数");
} } /**
* 定义狗对象
* @author Liudeli
*
*/
class Dog extends Animal{ } /**
* 子父类中的构造函数实例化过程
* @author Liudeli
*
*/
public class Demo1 { public static void main(String[] args) { Dog d = new Dog(); } }

没有去深究这个问题,大部分会回答,不输出任何,因为Dog类没有任何构造方法,如果这样想的其实就错了,它一定会输出父类无参构造方法的内容:

这是为什么呢?

答:其实只要我们随便创建一个类,就会有隐式的代码重点内容执行

会在子类的构造方法中执行 super(); 调用

/**
* 定义狗对象
* @author Liudeli
*
*/
class Dog extends Animal{ // 其实只要我们随便创建一个类,就会有隐式的代码执行,只是我们看不到而已
Dog() {
super();
return;
} }


子类有一个有参构造方法,new 子类(true),调用子类的有参构造方法,父类的无参构造方法一定会执行,因为在子类的任何构造方法中,都会默认调用 super();

package com.oop;

/**
* 定义动物对象
* @author Liudeli
*
*/
class Animal2 { public Animal2() {
System.out.println("Animal()--构造函数");
} public Animal2(boolean is) {
System.out.println("Animal2(boolean is)--构造函数 is:" + is);
} } /**
* 定义狗对象
* @author Liudeli
*
*/
class Dog2 extends Animal{ public Dog2() { } public Dog2(boolean is) {
System.out.println("Dog2(boolean is)--构造函数 is:" + is);
} } /**
* 子父类中的构造函数实例化过程
* @author Liudeli
*
*/
public class Demo2 { public static void main(String[] args) { // 我调用的是,子类的有参构造方法,父类的无参构造方法会执行
// 因为在子类的任何构造方法中,都会执行super();
Dog2 dog = new Dog2(true); } }

运行结果:



我们看不到的细节:

package com.oop;

/**
* 定义动物对象
* @author Liudeli
*
*/
class Animal3 { public Animal3() {
System.out.println("Animal()--构造函数");
} public Animal3(boolean is) {
System.out.println("Animal(boolean is)--构造函数 is:" + is);
} } /**
* 定义狗对象
* @author Liudeli
*
*/
class Dog3 extends Animal{ public Dog3() {
// super(); 默认就有,只是我们看不到而已,super()它在子类任何构造函数中的第一行
super(false); // 这样写报错,为什么会报错因为在子类的任何构造函数中都会执行 super()
// 你如果写了 super(参数); 就是不认它调用父类的super(), 所以它会报错
} public Dog3(boolean is) {
// super(); 默认就有,只是我们看不到而已,super()它在子类任何构造函数中的第一行
super(false); // 这样写报错,为什么会报错因为在子类的任何构造函数中都会执行 super()
// 你如果写了 super(参数); 就是不认它调用父类的super(), 所以它会报错
System.out.println("Dog(boolean is)--构造函数 is:" + is);
} } /**
* 子父类中的构造函数实例化过程
* @author Liudeli
*
*/
public class Demo3 { /*
* Demo3 的实例化必须执行以下代码,只是隐式的看不到而已
*/
// 主要 修饰符 public 是由于类开始定义的是public,所以它才是public,修饰符根据类的定义变化而变化
public Demo3() {
super();
return;
} public static void main(String[] args) { Dog3 dog = new Dog3(true); } }

在这里有一个思考点,创建一个类不继承任何类,默认无参构造函数必须执行 super(); ,那super调用了那个父类的无参构造函数?

答:最终超类 Object。

所以我们这样写,没有任何问题,extends Object

package com.oop;

// 系统默认或直接间接的让Object成为了父类,extends Object,只是我们看不到而已
public class Demo4 extends Object { /*
* Demo3 的实例化必须执行以下代码,只是隐式的看不到而已
*/
// 主要 修饰符 public 是由于类开始定义的是public,所以它才是public,修饰符根据类的定义变化而变化
public Demo4() {
super();
return;
} public static void main(String[] args) {
System.out.println("Demo4()...");
} }

运行结果:


父类写了一个有参构造方法,子类继承父类,子类必须要写一个和父类一样参数的构造方法,因为父类写了一个有参构造方法,父类的无参构造方法就没有了,子类的无参构造方法就调用不到父类的无参构造方法了,需要让子类的有参构造方法去super()调用;

public  class Observer {

    private String name;
private Secretary secretary; public Observer(String name, Secretary secretary) {
this.name = name;
this.secretary = secretary;
} }
public class StockObserver extends Observer{

    // 子类必须要写一个和父类同参的构造方法
public StockObserver(String name, Secretary secretary) {
super(name, secretary);
// TODO Auto-generated constructor stub
}
}

谢谢大家的观看,更多精彩技术博客,会不断的更新,请大家访问,

刘德利CSDN博客, http://blog.csdn.net/u011967006

Java子父类中的构造函数实例化过程的更多相关文章

  1. Java继承--子父类中的构造函数

    子父类中的构造函数的特点: 1.在子类构造对象时,发现,访问子类构造函数时,父类构造函数也运行了.   原因是:在子类的构造函数中第一行有一个默认的隐式语句. super(); 类似于this(); ...

  2. java基础课程笔记 static 主函数 静态工具类 classpath java文档注释 静态代码块 对象初始化过程 设计模式 继承 子父类中的函数 继承中的构造函数 对象转型 多态 封装 抽象类 final 接口 包 jar包

    Static那些事儿 Static关键字 被static修饰的变量成为静态变量(类变量) 作用:是一个修饰符,用于修饰成员(成员变量,成员方法) 1.被static修饰后的成员变量只有一份 2.当成员 ...

  3. JAVA 子父类的特点

    一.变量(属性)    this 代表当前对象的引用 this.变量 首先在本类中找所需要的这个变量,如果没有找到再去父类中找    super 用于访问当前对象的父类成员 super.变量 直接在父 ...

  4. java之父类中的构造器是否能被子类继承?

    子类默认继承父类的属性和方法,但不会继承父类的构造器,而是在子类被实例化时会默认调用父类的空构造器.子类在创建的时候会调用自己的空构造器,并在空构造器会隐式调用super(),即父类的空构造器.如果父 ...

  5. Spring中bean的实例化过程

    1.从缓存中.优先从一级缓存中拿,有则返回. 如果没有,则从二级缓存中获取,有则返回. 如果二级缓存中拿不到,则从三级缓存中拿,能拿到,则从三级缓存中删除,移到二级缓存. 如果三级缓存也没有,则返回n ...

  6. Java子线程中的异常处理(通用)

    在普通的单线程程序中,捕获异常只需要通过try ... catch ... finally ...代码块就可以了.那么,在并发情况下,比如在父线程中启动了子线程,如何正确捕获子线程中的异常,从而进行相 ...

  7. Java子线程中操作主线程Private级别数据

    两个类分别如下: <pre name="code" class="java">package Demo2; import java.util.*; ...

  8. 转:Java子线程中的异常处理(通用)

    引自:https://www.cnblogs.com/yangfanexp/p/7594557.html 在普通的单线程程序中,捕获异常只需要通过try ... catch ... finally . ...

  9. java的父类声明,子类实例化(强制类型转换导致异常ClassCastException)

    一.使用原因 父类声明,子类实例化,既可以使用子类强大的功能,又可以抽取父类的共性. 二.使用要点 1.父类类型的引用可以调用父类中定义的所有属性和方法: 2.父类中方法只有在是父类中定义而在子类中没 ...

随机推荐

  1. node.js实时编译,不需要重启

    npm -g install supervisor 全局安装这个,然后编译依一次文件就可以了,之后修改这个文件不用编译也可以了

  2. MD5摘要算法实现

    网上找到的实现md5函数代码,包括一个头文件md5.h和一个源文件md5.c,用下面的测试代码test.c测试通过,各文件依次如下: 头文件md5.h: #ifndef MD5_H #define M ...

  3. day5:vcp考试

    Q81. An administrator needs to recover disk space on a previously-used thin provisioned virtual disk ...

  4. 转载博客:rabbitmq

    原文出处:http://www.cnblogs.com/sam-uncle/p/9202933.html 假设有这一些比较耗时的任务,按照上一次的那种方式,我们要一直等前面的耗时任务完成了之后才能接着 ...

  5. 无法访问部署在linux上的Tomcat服务器解决方案

    笔者使用环境:CentOS 6.4  Windows7  tomcat7 主要原因是linux开启了防火墙,有两种解决方案,一种是关闭防火墙,另外一种是开放所要访问的端口 1.关闭防火墙(非常不建议) ...

  6. php Pthread 多线程 (二) Worker和Threaded

    <?php //Worker是具有持久化上下文(执行环境)的线程对象 //Worker对象start()后,会执行run()方法,run()方法执行完毕,线程也不会消亡 class MySqlW ...

  7. linux下iptables防火墙设置

    各位linux的爱好者或者工作跟linux相关的程序员,我们在工作中经常遇到应用服务器端口已经启动, 在网络正常的情况下,访问不到应用程序,这个跟防火墙设置有关 操作步骤 1.检查有没有启动防火墙 s ...

  8. 我的UI启蒙之路

    为什么叫UI启蒙之路呢? 我没有学过美术,也不懂设计,但是有的时候也许就是一种命中注定吧,让我知道了UI,并且一发不可收拾的爱上了它. 具体情况是这样的: 我毕业于电力学校,是一名不折不扣的工科生,专 ...

  9. Storm 系列(三)Storm 集群部署和配置

    Storm 系列(二)Storm 集群部署和配置 本章中主要介绍了 Storm 的部署过程以及相关的配置信息.通过本章内容,帮助读者从零开始搭建一个 Storm 集群. 一.Storm 的依赖组件 1 ...

  10. 11 Maven 灵活的构建

    Maven 灵活的构建 一个优秀的构建系统必须足够灵活,它应该能够让项目在不同的环境下都能成功地构建.例如,典型的项目都会有开发环境.测试环境和产品环境,这些环境的数据库配置不尽相同,那么项目构建的时 ...