Java课堂疑问解答与思考5
一:运行 TestInherits.java 示例,观察输出,总结。
TestInherits.java
class Grandparent
{
public Grandparent()
{
System.out.println("GrandParent Created.");
}
public Grandparent(String string)
{
System.out.println("GrandParent Created.String:" + string);
}
}
class Parent extends Grandparent
{
public Parent()
{
//super("Hello.Grandparent.");
System.out.println("Parent Created");
// super("Hello.Grandparent.");
}
}
class Child extends Parent
{
public Child()
{
System.out.println("Child Created");
}
}
public class TestInherits
{
public static void main(String args[])
{
Child c = new Child();
}
}
总结:
通过 super 调用基类构造方法,必须是子类构造方法中的第一个语句。否则会报错。运行结果如下:


为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来?
答:
构造一个对象,先调用其构造方法,来初始化其成员函数和成员变量。
子类拥有父类所有的变量及方法,父类没有子类的部分变量和方法。
如果不调用,则从父类继承而来的成员变量和成员方法得不到正确的初始化。
不能反过来调用也是这个原因,因为父类根本不知道子类有神魔变量而且这样一来子类也得不到初始化的父类变量,导致程序运行出错!
二、直接输出一个不可变的类的对象,会有什么结果?
程序源码示例:
class A{}
public class ExplorationJDKSource {
public static void main(String[] args) {
System.out.println(new A());
}
}
运行结果:类型名+@+随机数

原因:
main方法实际上调用的是祖类函数: public void println(Object x),这一方法内部调用了String类的valueOf方法。
valueOf方法内部又调用Object.toString方法:

hashCode()方法是本地方法,由JVM设计者实现: public native int hashCode();
所以通过层层调用结果就显示出了 类名+@+哈希值。
三、我们来看Fruit.java 代码,总结原因。
Fruit.java
public class Fruit
{
public String toString()
{
return "Fruit toString.";
}
public static void main(String args[])
{
Fruit f=new Fruit();
System.out.println("f="+f);
// System.out.println("f="+f.toString());
}
}
运行结果:

总结:
Fruit类覆盖了Object类的toString方法。
在“+”运算中,当任何一个对象与一个String对象,连接时,会隐式地调用其toString()方法,默认情况下,此方法返回“类名 @ + hashCode”。为了返回有意义的信息,子类可以重写toString()方法。
四、
现在有三个类:
class Mammal{}
class Dog extends Mammal {}
class Cat extends Mammal{}
针对每个类定义三个变量并进行初始化
Mammal m=null ;
Dog d=new Dog();
Cat c=new Cat();
下列语句哪一个将引起编译错误?为什么?哪一个会引起运行时错误?为什么?
m=d;
d=m;
d=(Dog)m;
d=c;
c=(Cat)m;
答:程序运行结果

第二行与第四行出错。
将父类赋值给子类时需要强制转化,子类赋值给父类时不用强制转化。父类的两个子类相互赋值时也必须强制转化。
五、请看下面的“变态”类。程序运行结果是什么?你如何解释会得到这样的输出? 计算机是不会出错的,之所以得 到这样的运行结果也是有原因的, 那么从这些运行结果中,你能总 结出Java的哪些语法特性?
程序源码:
class Parent{
public int myValue=100;
public void printValue() {
System.out.println("Parent.printValue(),myValue="+myValue);
}
}
class Child extends Parent{
public int myValue=200;
public void printValue() {
System.out.println("Child.printValue(),myValue="+myValue);
}
}
public class Fruit
{
public static void main(String[] args) {
Parent parent=new Parent();
parent.printValue();
Child child=new Child();
child.printValue();
parent=child;
parent.printValue();
parent.myValue++;
parent.printValue();
((Child)parent).myValue++;
parent.printValue();
}
}
运行结果:

总结:
当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。 这个特性实际上就是面向对象“多态”特性的具体表现。
如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。 如果子类被当作父类使用,则通过子类访问的字段是父类的!
Java课堂疑问解答与思考5的更多相关文章
- java课堂疑问解答与思考2
问题一 编写一个方法,使用以上算法生成指定数目(比如1000个)的随机整数. 答:Xn+1=(7^5*Xn)mod(2^31-1) 程序源码: import java.util.Random; imp ...
- java课堂疑问解答与思考1
问题一 Java类中只能有一个公有类吗?用Eclipse检测以下程序是否正确.是否在接口中同样适用. 答:一个源文件里必须稚嫩发有一个公有类,名称必须与文件名一致.以上程序经过编译没有提示错误.jav ...
- Java课堂疑问解答与思考4
一. 请运行以下示例代码StringPool.java,查看其输出结果.如何解释这样的输出结果?从中你能总结出什么? 答:定义的三个字符串如果相等,系统自动创建一个,并调用这个,对于由new创建的字符 ...
- Java课堂疑问解答与思考3
一. 两对整数明明完全一样,为何一个输出true,一个输出false? 答: 整数在小于127时都可以用常量池,因此第一次比较的的地址是取自同一个地址的数字,而第二次比较的数是创建了两个不同地址的对象 ...
- 一个想法(续五):IT联盟创业计划:现阶段进度公示、疑问解答及进行中的计划
前言: 首先今天是元宵节,先祝大伙元宵节快,单纯的快乐! 然后看看开展中的计划: IT联盟创业计划众筹发起:一个想法(续三):一份IT技术联盟创业计划书,开启众筹创业征程 IT联盟创业计划众筹进度:一 ...
- java面试题—精选30道Java笔试题解答(二)
摘要: java面试题-精选30道Java笔试题解答(二) 19. 下面程序能正常运行吗() public class NULL { public static void haha(){ System ...
- 阿里JAVA开发手册零度的思考理解(二)
转载请注明原创出处,谢谢! 说在前面 人生的大道上默默地走,就必须要有一盏灯亮着为你引导方向!而这盏灯抑或只是一句话,一句鼓励,一个赞美,一次承认,一次认可,一次相识一次交流-- 上篇文章:阿里JAV ...
- Java课堂笔记(零):内容索引
回想自己学习和使用Java的时间也是很长了.本科期间课堂上浅尝辄止地学习了点皮毛,后来也是搁置不用,未曾深入研究.研究生期间因为项目和实习的原因,基本算是重新拾起Java这门语言,并且接触到了Spri ...
- 20155237 第十一周java课堂程序
20155237 第十一周java课堂程序 内容一:后缀表达式 abcde/-f+ 内容二:实现Linux下dc的功能,计算后缀表达式的值 填充下列代码: import java.util.Scann ...
随机推荐
- regsvr32 驱动
1.将SYS驱动文件放到系统目录的SYSTEM32目录中.2.按WIN+R组合键,在运行框中输入:regsvr32 sys所在全路径,点击确定即可.
- Ubuntu下Cmake编译C++程序Helloworld
1.首选新建工程目录 mkdir helloworld 2.新建文件目录 cd helloworld mkdir bin mkdir lib mkdir src mkdir include mkdir ...
- Python之网路编程之粘包现象
一.什么是粘包 须知:只有TCP有粘包现象,UDP永远不会粘包 粘包不一定会发生 如果发生了:1.可能是在客户端已经粘了 2.客户端没有粘,可能是在服务端粘了 首先需要掌握一个socket收发消息的原 ...
- 详解WebService开发中四个常见问题(2)
详解WebService开发中四个常见问题(2) WebService开发中经常会碰到诸如WebService与方法重载.循环引用.数据被穿该等等问题.本文会给大家一些很好的解决方法. AD:WO ...
- Jenkins打包Maven项目
Jenkins是一个用于持续集成的服务,简单些说,就是提交代码后,点一下(也可以设置自动检测),系统会自动下载你的代码并编译,然后复制或上传到指定位置,并给所有相关人发送邮件. 一.环境搭建 1.下载 ...
- 【leetcode】1185. Day of the Week
题目如下: Given a date, return the corresponding day of the week for that date. The input is given as th ...
- JS分组
var SplitArray = function (N, Q) { var R = [], F; for (F = 0; F < Q.length;) R.push(Q.slice(F, F ...
- codevs 5935 小球 x
题目描述 Description 许多的小球一个一个的从一棵满二叉树上掉下来组成FBT(Full Binary Tree,满二叉树),每一时间,一个正在下降的球第一个访问的是非叶子节点.然后继续下降时 ...
- CVPR 2018 DeepGlobe
在刚刚结束的CVPR2018: DeepGlobe Road Extraction Challenge(全球卫星图像道路提取)比赛中,北京邮电大学信息与通信工程学院模式识别实验室张闯老师指导的研究生周 ...
- qtp识别验证码
花了两天时间才完整的完成识别验证码的登录操作,在网上看到很多关于验证码识别的方法,但是我用的qtp版本比较高级,所以还是要自己花心思研究.po上我的识别验证码的详细历程: 一.读取浏览器中的图片验证码 ...