向上造型中让我入坑的地方 (><)
今天周六,闲着蛋疼就报名参加了公司的一个java比赛,比赛地点某某大厦11楼会议室,想象中应该是能容纳上百人的超大会议室。没成想,到地方一看,只是一个
能容纳六七人的有圆形会议桌的小会议室。不过这仍然不能熄灭BZ因对Java热爱而燃起的满腔激情,于是满怀热情地投入到了比赛答题中。
一般这样的开头都会给人一种欲抑先扬的感觉,BZ这次当然也不例外...刚开始没做几题,就被其中的一个小题目给绊倒了,题目大体是这样的:
有两个类,一个叫BaseHole,如下所示:
public class BaseHole {
public int i = 1;
public BaseHole () {
bh();
}
public void bh () {
System.out.println("Base Hole - bh()");
}
}
另一个类继承了上面的BaseHole,如下所示:
public class UpConstrutorHole extends BaseHole{
public int i = 2;
public void bh () {
System.out.println("UpConstrutorHole - bh()");
}
public void uch () {
System.out.println("UpConstrutorHole - uch()");
}
}
然后运行如下代码:
public class UpConstructorClient {
public static void main(String[] args) {
BaseHole b = new UpConstrutorHole();// 第8行
System.out.println(b.i);// 第9行
UpConstrutorHole u = (UpConstrutorHole) b;
u.uch();// 第11行
u.bh();// 第12行
}
}
问8/9/11/12各行代码分别输出的结果是什么:
A.Base Hole - bh()
1
UpConstrutorHole - uch()
UpConstrutorHole - bh()
B.由于向上造型后b中没有uch()方法,所以第10行给b强转类型后仍然没有uch()方法,故第11行编译报错无法执行
C.Base Hole - bh()
2
UpConstrutorHole - uch()
UpConstrutorHole - bh()
D.UpConstrutorHole - bh()
2
UpConstrutorHole - uch()
UpConstrutorHole - bh()
E.UpConstrutorHole - bh()
1
UpConstrutorHole - uch()
UpConstrutorHole - bh()
本着诚实守信的原则,通过分析上题看看自己是否真正的深刻了解向上造型,务必要先在心里想好自己的答案再往下看。 对于向上造型,我之前知道的点基本就是以下两点:
1、向上造型后的对象,能引用的方法为:如果子类的方法满足重写父类方法的要求,则引用子类的方法,否则引的是父类的方法,毕竟对象的类型是父类类型;
2、向上造型,子类的属性不能覆盖父类。
通过以上两点,可知第9行是1,第12行是UpConstrutorHole - bh(),排除CD,还剩ABE,下面才是本题的重难点。
剩余的ABE总共涉及到两部分内容:
第一部分是B中的强制类型转换,同一个引用,为什么前者没有uch方法,而类型转换之后就有了呢?(所以B是不对的,仿佛是 在用貌似合理的话胡说八道,但是如果强制类型转换原理了解不清楚,很容易就被忽悠了,BZ就是很悲催的踩入了坑里 -- FK) 首先第8行那里进行向上造型,
new了一个UpConstrutorHole对象,就是说在堆内存中真真切切的生成了一个UpConstrutorHole对象,对象的实体数据中存放的就是这个类中的代码,这一点是
确定无疑的;其次,为什么把UpConstrutorHole对象赋值给b引用后就访问不到uch了呢?其实就是BaseHole类型的引用是有可见范围的,该可见范围
包括b中已有的方法属性跟被UpConstrutorHole类重写的方法,而UpConstrutorHole中的其余方法对该引用不可见,所以形成了向上造型的这种访问形式;
第三,为什么强制类型转换后就又能访问uch方法了呢?还是这个引用指针捣的鬼,强制类型转换后,引用的可见范围被改变,变为可以访问到UpConstrutorHole
类中的方法,所以又能引用到uch方法,虽然对象没变,引用地址没变,但是只要引用的类型变了其访问范围也会改变。至此,B的迷雾已经被拨开,pass掉。
第二部分,运行程序可知第8行输出的是UpConstrutorHole类中的bh方法打印的字符,为什么父类的构造器中执行的也是子类中重写的方法呢?其实这就要
追溯到对象初始化的时候的执行顺序了,翻阅了一下"圣经" - 《Thinking In Java》,发现有相关讲解,大意如下:
构造器初始化的顺序:
1、先将分配给对象的存储空间初始化为二进制的0;
2、在子类构造器执行前,先调用基类的构造器,此时如果基类的构造器中有子类重写的方法,会调用子类中的方法;
3、按顺序调用成员变量的初始化方法;
4、调用子类的构造器
而且后面还特意加了一句嘱咐:编写构造器时,尽可能的避免调用其他方法,尤其是非final跟private的方法。不然就可能出现如上题所示的莫名现象。
经此一役,发觉要学的东西仍然浩如烟海。还是那句话,学习之路,一定要多给自己灌鸡汤,Never at rest!
向上造型中让我入坑的地方 (><)的更多相关文章
- 小程序入坑(一)---如何引入iconfont 字体图标
最近一直忙于日常任务,其实是懒癌又犯了..........不过因为自己的“懒癌”,“不思进取”给自己挖了不少坑. 一,小程序工具的安装 打开简易小程序的官网https://mp.weixin.qq.c ...
- Java中的向上造型和向下造型等
package com.study.oop.day01; /** * 如果某个方法是静态 的,它的行为就不具有多态性 * @author LuHongGang * @date 2017年6月5日 ...
- python函数中把列表(list)当参数时的"入坑"与"出坑"
在Python函数中,传递的参数如果默认有一个为 列表(list),那么就要注意了,此处有坑!! 入坑 def f(x,li=[]): for i in range(x): li.append(i*i ...
- 反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) C#中缓存的使用 C#操作redis WPF 控件库——可拖动选项卡的TabControl 【Bootstrap系列】详解Bootstrap-table AutoFac event 和delegate的分别 常见的异步方式async 和 await C# Task用法 c#源码的执行过程
反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) 背景介绍: 为了平衡社区成员的贡献和索取,一起帮引入了帮帮币.当用户积分(帮帮点)达到一定数额之后,就会“掉落”一定数量的“帮帮 ...
- eclipse中导入外部包却无法查看对应源码或Javadoc的入坑指南
eclipse中导入外部包却无法查看对应源码或Javadoc的 入坑指南 出现这个错误的原因是,你虽然导入了.jar包,但没有配置对应的Javadoc或源码路径,所以在编辑器中无法查看源 码和对应AP ...
- RoboGuice 3.0 (一)入坑篇
RoboGuice是什么? 一个Android上的依赖注入框架. 依赖注入是什么? 从字面理解,这个框架做了两件事情,第一是去除依赖,第二是注入依赖.简单理解就是,将对象的初始化委托给一个容器控制器, ...
- [SSIS] 在脚本里面使用数据库连接字符串进行查询等处理, 入坑
入坑.!!!!! SSIS 中dts包 设置的 ADO.Net连接, 在传入脚本的时候, 我要使用 数据库连接,进行数据的删除操作. 于是我使用了 了如下的 代码 使用的是windows 身份验证, ...
- webpack入坑之旅(六)配合vue-router实现SPA
这是一系列文章,此系列所有的练习都存在了我的github仓库中vue-webpack,在本人有了新的理解与认识之后,会对文章有不定时的更正与更新.下面是目前完成的列表: webpack入坑之旅(一)不 ...
- webpack入坑之旅(五)加载vue单文件组件
这是一系列文章,此系列所有的练习都存在了我的github仓库中vue-webpack,在本人有了新的理解与认识之后,会对文章有不定时的更正与更新.下面是目前完成的列表: webpack入坑之旅(一)不 ...
随机推荐
- 关于U3D的.SDK对接
1,SDK对接原理:https://www.cnblogs.com/msxh/p/7220741.html 2,Unity ADS对接:https://blog.csdn.net/chenluwolf ...
- 每日一练ACM 2019.04.13
2019.04.13 第1002题:A+B Proble Ⅱ Problem DescriptionI have a very simple problem for you. Given two in ...
- 计算机爱好者协会技术贴markdown第四期
首先先让爱酱用CSDN自带的数学公式方法来闪瞎大家的钛合金狗眼: 有没有感觉到Markdown的强大!!!!! ## KaTeX数学公式 您可以使用渲染LaTeX数学表达式 [KaTeX](https ...
- mac 清理
1.iOS DeviceSupport -- ~/Library/Developer/Xcode/iOS DeviceSupport 这个可重新生成!在连接旧设备调试时,会重新自动生成. 2.iP ...
- IDEA的相关使用-----快捷键
转:https://blog.csdn.net/qq_35091777/article/details/80988165 IntelliJ Idea 常用快捷键列表 Alt+回车 导入包,自动修正Ct ...
- vb.net WIN32API 获取listview的值
Public Class Form1 Public Const LVM_FIRST As Short = &H1000S Public Const LVM_GETITEMCOUNT As In ...
- mybatis 中使用oracle merger into
项目背景:设计到excel导入,数据量也比较大,保证性能的情况下还要考虑到:如果数据中有这条数据的主键,则更新(update),不存在的情况,执行插入(insert). mybatis代码: < ...
- Python开发——13.操作系统、进程和线程
一.操作系统 1.定义 操作系统是用来协调.管理和控制计算机硬件和软件资源的系统程序,它位于硬件和应用程序之间.操作系统运行在内核态,拥有对所有硬件的完全访问权,可以执行机器能够运行的任何指令.软件的 ...
- PowerPoint 2013中创建自定义路径动画的方法
1.在幻灯片中选择对象,在“动画”选项卡的“高级动画”组中单击“添加动画”按钮,在打开的下拉列表中选择“自定义路径”选项,如图1所示. 图1 选择“自定义路径”选项 2.此时鼠标指针变为十字形,在幻灯 ...
- Centos 安装 mysql yum
http://www.cnblogs.com/007sx/p/7083143.html https://www.linode.com/docs/databases/mysql/how-to-insta ...