• 习题解答chapter04


    题目:

    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调试动图

    程序说明:

    package bookcode.ex6.part6_6;
    
    class Pare {
        int i = 3;
    
        Pare() {
            super();
        }
    };
    
    class Construct extends Pare {
        int i = 8;
    
        Construct() {
        }
    
        Construct(int num) {
            this();
        }
    
        public static void main(String args[]) {
            Construct ct = new Construct(9);
            System.out.println(ct.i);
            System.out.println(ct.getSuper());
        }
    
        int getSuper() {
            return super.i;
        }
    }
    

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

    实例化执行顺序总结:

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

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

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

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

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

    class FighterPlane {
        String name;
        int missileNum;
    
        public FighterPlane(String _name, int _missleNum) {
            this.name = _name;
            this.missileNum = _missleNum;
        }
    
        public void fire() {
            if (this.missileNum > 0) {
                System.out.println("now fire a missile !");
                this.missileNum -= 1;
            } else {
                System.out.println("No missile left !");
            }
    
        }
    }
    class A {
        FighterPlane fp;
    
        public A(FighterPlane fpp) {
            this.fp = fpp;      //A对象中拥有了FighterPlane对象的引用
        }
    
        public void invoke() {
             //A对象发送消息给FighterPlane的对象
            System.out.println(fp.name);
        }
    }public class Run {
        public Run() {
        }
    
        public static void main(String[] var0) {
            FighterPlane ftp = new FighterPlane("su35", 10);
             //产生A对象,并将ftp作为对象引用传入
            A a= new A(ftp);
            a.invoke();
        }
    }
    

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

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

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

    Java提供了两种多态机制——重载和覆盖。运行时多态指的是覆盖,在运行时根据输入参数动态选择不同的 成员方法执行,体现了一个类本身的多态性,使代码具有良好的拓展性。
    举例:同样的红烧鱼,厨师老师的红烧方法传给厨师徒弟后,厨师徒弟在红烧方法上做了改动,这是红烧方法的重写,就相当于 java 的方法重写。

    重写代码如下:

    class Ct{
        void hongshao(int a){
            System.out.println("这是厨师老师的红烧int的方法");
        }
    }
    
    class Cs extends Ct{
        void hongshao(int a) {
            System.out.println("这是厨师徒弟的红烧int的方法");
        }
    }
    

    重载代码如下:

    class Cs extends Ct{
        void hongshao(int a) {
            System.out.println("这是厨师徒弟的红烧int的方法");
        }
        void hongshao(float b) {
            System.out.println("这是厨师徒弟红烧float的方法");
        }
        void hongshao(int a,float b) {
            System.out.println("这是厨师徒弟红烧int和float的方法");
        }
    }
    

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

    创建接口

    package bookcode.ex6.part6_8;
    
    public interface Shape {
        double getArea();
        double getPerimeter();
        void show();
    }
    

    圆类

    package bookcode.ex6.part6_8;
    
    public class Circle implements Shape{
        private int r;
        public Circle(int _r){
            r = _r;
        }
    
        @Override
        public double getArea() {
            return r * r * Math.PI;
        }
    
        @Override
        public double getPerimeter() {
            return 2 * Math.PI * r;
        }
    
        @Override
        public void show() {
            System.out.println("Circle Area:" + getArea());
            System.out.println("Circle Perimeter:" + getPerimeter());
        }
    }
    

    矩形类

    package bookcode.ex6.part6_8;
    
    public class Rect implements Shape {
    
        private int k;
        private int m;
    
        public Rect(int width, int height) {
            k = width;
            m = height;
        }
    
        public double getArea() {
            return (k * m);
        }
    
        public double getPerimeter() {
            return (2 * k + 2 * m);
        }
    
        @Override
        public void show() {
            System.out.println("Rect Area:" + getArea());
            System.out.println("Rect Perimeter:" + getPerimeter());
        }
    }
    

    三角形类

    package bookcode.ex6.part6_8;
    
    import com.sun.tools.javac.file.SymbolArchive;
    
    public class Triangle implements Shape{
        private int x, y, z, m;
        public Triangle(int _x, int _y, int _z){
            x = _x;
            y = _y;
            z = _z;
            m = (x + y +z) / 2;
        }
    
        @Override
        public double getArea() {
            return (Math.sqrt(m *(m - x) * (m - y) * (m - z)));
        }
    
        @Override
        public double getPerimeter() {
            return 2 * m;
        }
    
        @Override
        public void show() {
            System.out.println("Triangle Area:" + getArea());
            System.out.println("Triangle Perimeter:" + getPerimeter());
        }
    }
    

    运行

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

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

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

    package bookcode.ex6.part6_15;
    
    class Uncle{}
    class Pare{}
    class Pare1 extends Pare{}
    class Pare2 extends Pare1{}
    
    public class InstanceofTest {
    
        public static void main(String args[]) {
            Uncle uncle = new Uncle();
            Pare pare = new Pare();
            Pare1 pare1 = new Pare1();
            Pare2 pare2 = new Pare2();
    
            //验证pare
            if (pare instanceof Pare) {
                System.out.println("pare instanceof Pare");
            }
            if (!(pare instanceof Pare1)){
                System.out.println("pare not instanceof Pare1");
            }else if (pare instanceof Pare1){
                System.out.println("pare instanceof Pare1");
            }
            if(!(pare instanceof Pare2)){
                System.out.println("pare not instanceof Pare2");
            }else if (pare instanceof Pare2){
                System.out.println("pare instanceof Pare2");
            }
            System.out.println();
    
            //验证pare1
            if (pare1 instanceof Pare1) {
                System.out.println("pare instanceof Pare");
            }
            if (!(pare1 instanceof Pare)){
                System.out.println("pare1 not instanceof Pare");
            }else if(pare1 instanceof Pare){
                System.out.println("pare1 instanceof Pare");
            }
            if(!(pare1 instanceof Pare2)){
                System.out.println("pare1 not instanceof Pare2");
            }else if(pare1 instanceof Pare2){
                System.out.println("pare1 instanceof Pare2");
            }
            System.out.println();
    
            //验证pare2
            if (pare2 instanceof Pare2) {
                System.out.println("pare instanceof Pare");
            }
            if (!(pare2 instanceof Pare)){
                System.out.println("pare2 not instanceof Pare");
            }else if (pare2 instanceof Pare){
                System.out.println("pare2 instanceof Pare");
            }
            if(!(pare2 instanceof Pare1)){
                System.out.println("pare2 not instanceof Pare1");
            }else if (pare2 instanceof Pare1){
                System.out.println("pare2 instanceof Pare1");
            }
            System.out.println();
    
            //验证uncle
            if (uncle instanceof Uncle){
                System.out.println("uncle instanceof Uncle");
            }
            // 语法错误,无法编译通过
            /*
            if (uncle instanceof Pare) {
                System.out.println("uncle instanceof Pare");
            }else {
                System.out.println("uncle instanceof Pare");
            }
            if (!(uncle instanceof Pare1)){
                System.out.println("uncle not instanceof Pare1");
            }else {
                System.out.println("uncle instanceof Pare1");
            }
            if(!(uncle instanceof Pare2)){
                System.out.println("uncle not instanceof Pare2");
            }else {
                System.out.println("uncle instanceof Pare2");
            }
            */
    
    
        }
    }
    
    成本最低的事情是学习,性价比最高的事情也是学习!
  • 相关阅读:
    从简单做起ASP.NET复合控件(修定版)(注意在OnInit裡面設置好ID,否則無法在回傳時獲取控件值)
    多态的概念和作用
    Web设计师应该收藏的11个网站
    C++、Java与.NET——与同学讨论学习方向
    Asp.Net服务器控件编程学习记录:第一个Callback控件
    ASP.NET服务器控件开发(1)封装html
    javascript获取frameset中各个模块中的数据
    你去创业太老了
    呈现控件时出错,未将对象的引用设置到对象的实例(未創建子控件。。。)
    ASP.NET的Web Resources 设置教程
  • 原文地址:https://www.cnblogs.com/qiaofutu/p/13849023.html
Copyright © 2020-2023  润新知