Think In Java读书笔记:内部类覆盖及其初始化
本文相关章节:第十章 内部类 10.10 内部类可以被覆盖吗
在读至本节第二个范例代码时(及下方的代码),我对输出结果中的第一个“Egg.Yolk()”很不理解,为什么它会第一个地方输出。
我起初认为是在调用BigEgg.Yolk的构造器时初始化其父类调用父类构造器输出的,毕竟在main方法中第一行是在调用BigEgg的构造器,而它的构造器中首先调用了BigEgg.Yolk的构造器,在调用BigEgg.Yolk构造器时初始化其父类Egg.Yolk才输出的“Egg.Yolk()”。但书中却明确说明了第二个“EGG.Yolk()”是子类BigEgg.Yolk初始化其父类输出的,这就使我产生了迷惑——那第一个“Egg.Yolk()”到底是怎么输出的呢?
(书中范例代码,原文中因为是第二个范例所有的类都命名为“xxx2”,在这里我将所有的2都删去了)
/**
* Created by dsa44 on 2018/4/21.
*/
class Egg{ class Yolk{
public Yolk(){
System.out.println("Egg.Yolk()");
}
public void f(){
System.out.println("Egg.Yolk.f()");
}
} private Yolk y = new Yolk(); public Egg(){
System.out.println("new Egg()");
} public void insertYolk(Yolk yy){
y = yy;
} public void g(){
y.f();
}
}
public class BigEgg extends Egg{ public class Yolk extends Egg.Yolk{ public Yolk() {
System.out.println("BigEgg.Yolk()");
} public void f(){
System.out.println("BigEgg.Yolk.f()");
}
} public BigEgg(){
insertYolk(new Yolk());
} public static void main(String[] args){
Egg e = new BigEgg();
e.g();
}
}/* 输出结果
Egg.Yolk()
new Egg()
Egg.Yolk()
BigEgg.Yolk()
BigEgg.Yolk.f()
*/
这其中的关键点也是书中没提到的我认为就是BigEgg构造器到底是在何时开始运行的(实际上也只有BigEgg的构造器没有输出任何信息),于是我在BigEgg的构造器中添加了输出“new BigEgg()”的语句。结果如下:
我想在这里就已经真相大白了:
在调用BigEgg构造器时,其构造器首先调用了其父类Egg的构造器(即首先初始化它自己的父类),在初始化父类Egg时首先初始化了父类的数据域,而它的父类Egg的数据域只有一个私有的Egg.Yolk类型的引用y,且在这里对y进行了初始化,调用它的构造器Egg.Yolk(),故输出了第一句“Egg.Yolk()”。
在初始化Egg的数据域后便运行了Egg的构造器(输出“new Egg()”),在自己的父类完成初始化后BigEgg的构造器开始运行(输出“new BigEgg()”),然后运行父类Egg的方法insertYolk,在其参数部分运行BigEgg.Yolk的构造器,在这里就变成了我刚开始提到的那一部分,于是相继输出了“Egg.Yolk()”“BigEgg.Yolk()”,最后虽然BigEgg.Yolk向上转型,但因为动态绑定的关系,在调用e.f()时,依旧输出的时属于BigEgg.Yolk的f方法,输出“BigEgg.Yolk.f()”。
总结:在这里遇到问题的主要原因还是因为对于第五章初始化部分了解的不够详细(知识点:父类初始化是在子类构造器未运行前就进行的,也可以说是在调用子类构造器时就开始了父类的初始化并在其初始化完成后开始运行子类的构造器)。
Think In Java读书笔记:内部类覆盖及其初始化的更多相关文章
- head first java读书笔记
head first java读书笔记 1. 基本信息 页数:689 阅读起止日期:20170104-20170215 2. 标签 Java入门 3. 价值 8分 4. 主题 使用面向对象的思路介绍J ...
- think in java 读书笔记 3 —— 数据报
目录 think in java 读书笔记 1 ——移位 think in java 读书笔记 2 —— 套接字 think in java 读书笔记 3 —— 数据报 概要 1. 数据报基本知识 2 ...
- think in java 读书笔记 2 —— 套接字
目录 think in java 读书笔记 1 ——移位 think in java 读书笔记 2 —— 套接字 think in java 读书笔记 3 —— 数据报 概要 1. 套接字基本知识 2 ...
- think in java 读书笔记 1 ——移位
目录 think in java 读书笔记 1 ——移位 think in java 读书笔记 2 —— 套接字 think in java 读书笔记 3 —— 数据报 在Think in Java中 ...
- Thinking In Java读书笔记--对象导论
Thinking In Java读书笔记--对象导论[对象]服务提供者==>将对象看做一个服务提供者[程序员分类][类创造者]/[客户端程序员] [访问控制存在的原因?][1]客户端程序员无法触 ...
- TIJ读书笔记08-数组的初始化和可变长参数形参
TIJ读书笔记08-数组的初始化和可变参数形参 数组 数组的声明 数组的初始化和赋值 可变参数列表 数组 相同类型的,用一个标识符名称封装到一起的一个对象序列或者基本数据类型序列叫数组.(多么严谨的概 ...
- Java读书笔记1
Java逍遥游记读书笔记 前言 必须先来一句,这是入门级别,高手勿喷~ 写Android的时候总有一些语句不是很理解,其实大部分是Java的内容,所以想系统的学下Java. 这本书——<Java ...
- java读书笔记二
这是我的一些读书笔记: 我研究了一下面向对象: 面向对象符合人类看待事物的一般规律,对象的方法的实现细节是包装的,只有对象方法的实现者了解细节 我觉得面向过程是由过程.步骤.函数组成,过程是核心,面向 ...
- Effective Java读书笔记完结啦
Effective Java是一本经典的书, 很实用的Java进阶读物, 提供了各个方面的best practices. 最近终于做完了Effective Java的读书笔记, 发布出来与大家共享. ...
- 初读"Thinking in Java"读书笔记之第七章 --- 复用类
组合语法 将对象引用置于新类中,即形成类的组合. 引用初始化方法 在定义处初始化. 在类的构造器中初始化. 在使用这些对象之前,进行"惰性初始化". 使用实例初始化. 继承语法 J ...
随机推荐
- Redis简介和常见的面试题
redis介绍及特点 Redis是由意大利人Salvatore Sanfilippo开发的一款内存内存高速缓存数据库. Reids全称为:Remote Dictionary Server(远程数据服务 ...
- 【数据结构与算法】003—排序算法(Python)
写在前面 常见排序算法可以分为两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序. 线性时间非比较类排序:不通过比较 ...
- Scala_单例对象
在 Scala 中,是没有 static 这个东西的,但是它也为我们提供了单例模式的实现方法,那就是使用关键字 object. 对象的无参构造器在第一次使用时被调用,且单例对象没有有残构造器. Enu ...
- 用NI的数据采集卡实现简单电子测试之2——绘制三极管输出特性曲线(面)图
本文从本人的163博客搬迁至此. 想设计几个实验,既能展示NI的LabVIEW和数据采集卡的功能特点,又能够让普通电类专业本科学生可以理解,自然首先想到了<电子技术基础>课程的内容.第一个 ...
- JavaWeb基础—项目名的写法
${pageContext.request.contextPath} //jsp中 request.getContextPath() //Servlet中 两者获取到的都是"/项目名称&qu ...
- C# 获取北京时间 (根据纪元时间(1970/1/1)转换为DateTime)
根据纪元时间(1970/1/1)转换为DateTime WebClient wc = new WebClient(); s= wc.DownloadString("http://api.ti ...
- Linux下开发python django程序(Cookie读写)
1.设置cookie信息(登陆成功后设置登陆用户名,有效期1小时) def login(req): if req.method == 'POST': loginform = LoginForm(req ...
- js获取字符串字节数方法小结
js获取字符串字节数的方法.分享给大家供大家参考.具体如下: 大家都知道,获取字符串的长度可用length来获取,那么获取这段字符串的字节数呢? 英文字母肯定lenght和字节数都一样:都是1而中文l ...
- 一个针对string的较好的散列算发djb2
var djb2HashCode = function(key) { var hash = 5831; for(var i = 0; i < key.length; i++) { hash = ...
- java抽象类与接口区别
java抽象类与接口区别: abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力. abstr ...