题目:

  1. 实验:利用IDE的debug功能给例6.4和例6.6的new语句设置断点,使用单步调试(step into/step over)跟踪子类对象实例化(初始化)的执行顺序,并总结该过程。(教材:Java面向对象程序设计,第二版,袁绍欣主编)
  2. 如何实现两个对象之间互发消息,请举例说明。
  3. 谈谈组合与继承的区别以及两者的使用场景(即什么时候宜用组合?什么时候宜用继承? )。
  4. Java中的运行时多态的含义是什么?有什么作用?请举例说明。
  5. 使用接口改写例6.8中的程序。
  6. 简述运算符instanceof的使用场景。

1. 实验:利用IDE的debug功能给例6.4和例6.6的new语句设置断点,使用单步调试(step into/step over)跟踪子类对象实例化(初始化)的执行顺序,并总结该过程。

下面给出6.4调试动图(大小限制,该动图尺寸不大)



下面给出6.6调试动图



程序说明:

  1. package bookcode.ex6.part6_6;
  2. class Pare {
  3. int i = 3;
  4. Pare() {
  5. super();
  6. }
  7. };
  8. class Construct extends Pare {
  9. int i = 8;
  10. Construct() {
  11. }
  12. Construct(int num) {
  13. this();
  14. }
  15. public static void main(String args[]) {
  16. Construct ct = new Construct(9);
  17. System.out.println(ct.i);
  18. System.out.println(ct.getSuper());
  19. }
  20. int getSuper() {
  21. return super.i;
  22. }
  23. }

先执行的是子类的this(),Construct()中有一个隐含的super(),使得类Construct在生成对象时,父类 i=3 显式初始化能够执行。

实例化执行顺序总结:

  • 为子类对象分配内存空间,对域变量进行默认初始化。
  • 绑定构造方法,将new对象中的参数传递给构造方法的形式参数。
  • 调用this或super语句,二者必居其一,也只有一。
  • 进行实例变量的显式初始化操作。
  • 执行当前构造方法体中的程序代码。

2. 如何实现两个对象之间互发消息,请举例说明。

使用引用的属性或方法其实都是调用对象的属性或方法,而消息概念的引入就是为了说明这样的过程。消息的实质就是引用向对象发出的服务请求,是对数据成员和成员方法的调用。下面列举能否发送消息的三个条件:

  • 引用必须真实引用了特定的对象,否则会抛出NullPointerException异常。
  • 访问对象必须定义了相应的属性或方法,否则编译不会通过。
  • 被访问的属性或方法必须具有可访问的权限。

消息也就是相当于在遥控器和显示器之间架起沟通的桥梁。在面向对象语言中,消息把不同对象相互联系起来,共同完成特定功能。

实例代码:

  1. class FighterPlane {
  2. String name;
  3. int missileNum;
  4. public FighterPlane(String _name, int _missleNum) {
  5. this.name = _name;
  6. this.missileNum = _missleNum;
  7. }
  8. public void fire() {
  9. if (this.missileNum > 0) {
  10. System.out.println("now fire a missile !");
  11. this.missileNum -= 1;
  12. } else {
  13. System.out.println("No missile left !");
  14. }
  15. }
  16. }
  17. class A {
  18. FighterPlane fp;
  19. public A(FighterPlane fpp) {
  20. this.fp = fpp; //A对象中拥有了FighterPlane对象的引用
  21. }
  22. public void invoke() {
  23. //A对象发送消息给FighterPlane的对象
  24. System.out.println(fp.name);
  25. }
  26. }public class Run {
  27. public Run() {
  28. }
  29. public static void main(String[] var0) {
  30. FighterPlane ftp = new FighterPlane("su35", 10);
  31. //产生A对象,并将ftp作为对象引用传入
  32. A a= new A(ftp);
  33. a.invoke();
  34. }
  35. }

3. 谈谈组合与继承的区别以及两者的使用场景(即什么时候宜用组合?什么时候宜用继承? )。

  • 组合:通过对象内部的属性引用来实现。使对象之间的耦合性较为松散。
  • 继承:从已有的类派生出新的类。在不同的类中也可能会有共同的特征和动作,可以把这些共同的特征和动作放在一个类中,让其它类共享。因此可以定义一个通用类,然后将其扩展为其它多个特定类,这些特定类继承通用类中的特征和动作。继承是 Java 中实现软件重用的重要手段,避免重复,易于维护,易于理解。
  • 组合就像房间里面的窗户、墙壁、地板、桌子、椅子等,他们之间并不存在结构上的相似性,只是功能上组合可以发挥更大的作用,但是单独是可以独立运行的。继承就像对房间进行拓展成为一栋楼,前面的零部件它都具备,但是如果没有房间,大楼是无法构建的,具有结构和功能上的关联。
  • 显而易见,在不具有结构和功能上的相似性时,使用继承可以减少代码重复率,易于维护;在结构实现不同、功能“可叠加”时,使用组合无疑是优于继承的。

4. Java中的运行时多态的含义是什么?有什么作用?请举例说明。

Java提供了两种多态机制——重载和覆盖。运行时多态指的是覆盖,在运行时根据输入参数动态选择不同的 成员方法执行,体现了一个类本身的多态性,使代码具有良好的拓展性。

举例:同样的红烧鱼,厨师老师的红烧方法传给厨师徒弟后,厨师徒弟在红烧方法上做了改动,这是红烧方法的重写,就相当于 java 的方法重写。

重写代码如下:

  1. class Ct{
  2. void hongshao(int a){
  3. System.out.println("这是厨师老师的红烧int的方法");
  4. }
  5. }
  6. class Cs extends Ct{
  7. void hongshao(int a) {
  8. System.out.println("这是厨师徒弟的红烧int的方法");
  9. }
  10. }

重载代码如下:

  1. class Cs extends Ct{
  2. void hongshao(int a) {
  3. System.out.println("这是厨师徒弟的红烧int的方法");
  4. }
  5. void hongshao(float b) {
  6. System.out.println("这是厨师徒弟红烧float的方法");
  7. }
  8. void hongshao(int a,float b) {
  9. System.out.println("这是厨师徒弟红烧int和float的方法");
  10. }
  11. }

5. 使用接口改写例6.8中的程序。

创建接口

  1. package bookcode.ex6.part6_8;
  2. public interface Shape {
  3. double getArea();
  4. double getPerimeter();
  5. void show();
  6. }

圆类

  1. package bookcode.ex6.part6_8;
  2. public class Circle implements Shape{
  3. private int r;
  4. public Circle(int _r){
  5. r = _r;
  6. }
  7. @Override
  8. public double getArea() {
  9. return r * r * Math.PI;
  10. }
  11. @Override
  12. public double getPerimeter() {
  13. return 2 * Math.PI * r;
  14. }
  15. @Override
  16. public void show() {
  17. System.out.println("Circle Area:" + getArea());
  18. System.out.println("Circle Perimeter:" + getPerimeter());
  19. }
  20. }

矩形类

  1. package bookcode.ex6.part6_8;
  2. public class Rect implements Shape {
  3. private int k;
  4. private int m;
  5. public Rect(int width, int height) {
  6. k = width;
  7. m = height;
  8. }
  9. public double getArea() {
  10. return (k * m);
  11. }
  12. public double getPerimeter() {
  13. return (2 * k + 2 * m);
  14. }
  15. @Override
  16. public void show() {
  17. System.out.println("Rect Area:" + getArea());
  18. System.out.println("Rect Perimeter:" + getPerimeter());
  19. }
  20. }

三角形类

  1. package bookcode.ex6.part6_8;
  2. import com.sun.tools.javac.file.SymbolArchive;
  3. public class Triangle implements Shape{
  4. private int x, y, z, m;
  5. public Triangle(int _x, int _y, int _z){
  6. x = _x;
  7. y = _y;
  8. z = _z;
  9. m = (x + y +z) / 2;
  10. }
  11. @Override
  12. public double getArea() {
  13. return (Math.sqrt(m *(m - x) * (m - y) * (m - z)));
  14. }
  15. @Override
  16. public double getPerimeter() {
  17. return 2 * m;
  18. }
  19. @Override
  20. public void show() {
  21. System.out.println("Triangle Area:" + getArea());
  22. System.out.println("Triangle Perimeter:" + getPerimeter());
  23. }
  24. }

运行

  1. package bookcode.ex6.part6_8;
  2. public class RunShape{
  3. public static void main(String args[]){
  4. Rect rect = new Rect(5 , 6);
  5. Triangle triangle = new Triangle(3, 4, 5);
  6. Circle circle = new Circle(5);
  7. rect.show();
  8. System.out.println();
  9. triangle.show();
  10. System.out.println();
  11. circle.show();
  12. }
  13. }

6. 简述运算符instanceof的使用场景。

instanceof 是 Java 的一个二元操作符,instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类或子类的实例,返回 boolean 的数据类型。

  1. package bookcode.ex6.part6_15;
  2. class Uncle{}
  3. class Pare{}
  4. class Pare1 extends Pare{}
  5. class Pare2 extends Pare1{}
  6. public class InstanceofTest {
  7. public static void main(String args[]) {
  8. Uncle uncle = new Uncle();
  9. Pare pare = new Pare();
  10. Pare1 pare1 = new Pare1();
  11. Pare2 pare2 = new Pare2();
  12. //验证pare
  13. if (pare instanceof Pare) {
  14. System.out.println("pare instanceof Pare");
  15. }
  16. if (!(pare instanceof Pare1)){
  17. System.out.println("pare not instanceof Pare1");
  18. }else if (pare instanceof Pare1){
  19. System.out.println("pare instanceof Pare1");
  20. }
  21. if(!(pare instanceof Pare2)){
  22. System.out.println("pare not instanceof Pare2");
  23. }else if (pare instanceof Pare2){
  24. System.out.println("pare instanceof Pare2");
  25. }
  26. System.out.println();
  27. //验证pare1
  28. if (pare1 instanceof Pare1) {
  29. System.out.println("pare instanceof Pare");
  30. }
  31. if (!(pare1 instanceof Pare)){
  32. System.out.println("pare1 not instanceof Pare");
  33. }else if(pare1 instanceof Pare){
  34. System.out.println("pare1 instanceof Pare");
  35. }
  36. if(!(pare1 instanceof Pare2)){
  37. System.out.println("pare1 not instanceof Pare2");
  38. }else if(pare1 instanceof Pare2){
  39. System.out.println("pare1 instanceof Pare2");
  40. }
  41. System.out.println();
  42. //验证pare2
  43. if (pare2 instanceof Pare2) {
  44. System.out.println("pare instanceof Pare");
  45. }
  46. if (!(pare2 instanceof Pare)){
  47. System.out.println("pare2 not instanceof Pare");
  48. }else if (pare2 instanceof Pare){
  49. System.out.println("pare2 instanceof Pare");
  50. }
  51. if(!(pare2 instanceof Pare1)){
  52. System.out.println("pare2 not instanceof Pare1");
  53. }else if (pare2 instanceof Pare1){
  54. System.out.println("pare2 instanceof Pare1");
  55. }
  56. System.out.println();
  57. //验证uncle
  58. if (uncle instanceof Uncle){
  59. System.out.println("uncle instanceof Uncle");
  60. }
  61. // 语法错误,无法编译通过
  62. /*
  63. if (uncle instanceof Pare) {
  64. System.out.println("uncle instanceof Pare");
  65. }else {
  66. System.out.println("uncle instanceof Pare");
  67. }
  68. if (!(uncle instanceof Pare1)){
  69. System.out.println("uncle not instanceof Pare1");
  70. }else {
  71. System.out.println("uncle instanceof Pare1");
  72. }
  73. if(!(uncle instanceof Pare2)){
  74. System.out.println("uncle not instanceof Pare2");
  75. }else {
  76. System.out.println("uncle instanceof Pare2");
  77. }
  78. */
  79. }
  80. }

习题解答chapter04的更多相关文章

  1. (搬运)《算法导论》习题解答 Chapter 22.1-1(入度和出度)

    (搬运)<算法导论>习题解答 Chapter 22.1-1(入度和出度) 思路:遍历邻接列表即可; 伪代码: for u 属于 Vertex for v属于 Adj[u] outdegre ...

  2. DirectX 11游戏编程学习笔记之8: 第6章Drawing in Direct3D(在Direct3D中绘制)(习题解答)

            本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com         注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...

  3. 《Programming Massively Parallel Processors》Chapter5 习题解答

    自己做的部分习题解答,因为时间关系,有些马虎,也不全面,欢迎探讨或指出错误 5.1 Consider the matrixaddition in Exercise 3.1. Can one use s ...

  4. 现代控制理论习题解答与Matlab程序示例

    现代控制理论习题解答与Matlab程序示例 现代控制理论 第三版 课后习题参考解答: http://download.csdn.net/detail/zhangrelay/9544934 下面给出部分 ...

  5. 機器學習基石(Machine Learning Foundations) 机器学习基石 作业三 课后习题解答

    今天和大家分享coursera-NTU-機器學習基石(Machine Learning Foundations)-作业三的习题解答.笔者在做这些题目时遇到非常多困难,当我在网上寻找答案时却找不到,而林 ...

  6. Coursera公开课Functional Programming Principles in Scala习题解答:Week 2

    引言 OK.时间非常快又过去了一周.第一周有五一假期所以感觉时间绰绰有余,这周中间没有假期仅仅能靠晚上加周末的时间来消化,事实上还是有点紧张呢! 后来发现每堂课的视频还有相应的课件(Slide).字幕 ...

  7. 《C++编程思想》第四章 初始化与清除(原书代码+习题+解答)

    相关代码: 1. #include <stdio.h> class tree { int height; public: tree(int initialHeight); ~tree(); ...

  8. 《C++Primer》第五版习题解答--第四章【学习笔记】

    [C++Primer]第五版习题解答--第四章[学习笔记] ps:答案是个人在学习过程中书写,可能存在错漏之处,仅作参考. 作者:cosefy Date: 2020/1/11 第四章:表达式 练习4. ...

  9. 快学Scala习题解答—第一章 基础

    1 简介 近期对Scala比较感兴趣,买了本<快学Scala>,感觉不错.比<Programming Scala:Tackle Multi-Core Complexity on th ...

随机推荐

  1. MaaS系统概述

    摘要:共享经济正改变着人们的生活方式,城市公共交通系统应该顺应共享经济的潮流进行转型.近年来,西方国家提出的“出行即服务(MaaS)”理念为我国解决日益严重的城市交通拥堵问题提供了新的思路.基于Maa ...

  2. Shell学习(一)认识Shell

    一.啥是Shell Shell : 一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言. Shell脚本 :  一种为 shell 编写的 ...

  3. 趣图:我说自己菜 vs 大佬说自己菜

      扩展阅读 一大波趣图:CSS的力量 趣图:嫁人就嫁程序员,大妈都懂的! 趣图:向客户介绍的产品VS实际开发的产品 如何准备校招技术面试+一只小菜鸟的面试之路 向Spring大佬低头--大量源码流出 ...

  4. python的全局函数

    1.Python的全局函数 import builtins dir(builtins)  abs  # 返回参数的绝对值 可以写成函数:def absnum): if num >=0: retu ...

  5. JavaScript创建对象的方式汇总

    1.Object构造函数创建 // 1.Object构造函数创建 var Obj = new Object(); Obj.name='saoge'; Obj.say=function(){ conso ...

  6. Processing 高效控制管理图形方法(一)

    之前在CSDN上发表过: https://blog.csdn.net/fddxsyf123/article/details/62456299

  7. 永久改变cmd背景颜色

    问题描述:cmd窗口为白底黑字,用久之后想换背景颜色. 解决方法一: win+R 输入regedis进入注册表,找到 HKEY_CURRENT_USER\Software\Microsoft\Comm ...

  8. Java泛型中的类型参数和通配符类型

    类型参数 泛型有三种实现方式,分别是泛型接口.泛型类.泛型方法,下面通过泛型方法来介绍什么是类型参数. 泛型方法声明方式:访问修饰符 <T,K,S...> 返回类型 方法名(方法参数){方 ...

  9. Emgu.CV怎么加载Bitmap

    EmguCV 在4.0.1版本之后没办法用Bitmap创建Image了. 我给大家说下 EmguCV怎么加载Bitmap 下边是 EmguCV 官方文档写的,意思是从4.0.1以后的版本不能直接Bit ...

  10. BUUCTF-[极客大挑战 2019]BabySQL 1 详解

    打开靶机 应该是love sql惹的事吧,来了个加强版本的sql注入,不过我们先输入账号密码看有什么反应 整一手万能密码,闭合双引号?username=admin&password=admin ...