Java习题解答05

问答题

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

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;
    }
}

实例化执行顺序总结:

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

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

使用引用的属性或方法其实都是调用对象的属性或方法,而消息概念的引入就是为了说明这样的过程。消息的实质就是引用向对象发出的服务请求,是对数据成员和成员方法的调用。下面列举能否发送消息的三个条件:
1.引用必须真实引用了特定的对象,否则会抛出NullPointerException异常。
2.访问对象必须定义了相应的属性或方法,否则编译不会通过。
3.被访问的属性或方法必须具有可访问的权限。
消息也就是相当于在遥控器和显示器之间架起沟通的桥梁。在面向对象语言中,消息把不同对象相互联系起来,共同完成特定功能。
实例代码:

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();
}
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());
    }
}
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());
    }
}
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());
    }
}
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的使用场景。

运算符的格式为:“a instanceofof A”,其中a为对象的引用,A为类。如果a为对象A的实例或A子类的实例,则会返回true;如果a为A父类的实例,则返回false;如果a对象的类和A没有任何关系,则编译不会通过。即instanceof比较的结果有三种:true、false、语法错误(编译不会通过)。

class Uncle{}
class Pare{}
class Pare1 extends Pare{}
class Pare2 extends Pare1{}
class Pare3{
    public class void main(String args[]) {
        Uncle u = new Uncle();
        Pare p = new Pare();
        Pare1 p1 = new Pare1();
        Pare2 p2 = new Pare2();
        if (p instanceof Pare) {
            System.out.println("p instanceof Pare");
        }
        if (!(p1 instanceof Pare1)) {
            System.out.println("p1 not instanceof Pare");
        } else {
            System.out.println("p1 instanceof Pare");
        }
        if (p2 instanceof Pare) {
            System.out.println("p2 instanceof Pare");
        }
        if (p1 instanceof Pare1) {
            System.out.println("p1 instanceof Pare1");
        }
        if (p2 instanceof Pare1) {
            System.out.println("p2 instanceof Pare1");
        }
        if (p1 instanceof Pare2) {
            System.out.println("p1 instanceof Pare2");
        } else {
            System.out.println("p1 not instanceof Pare2");
        }
        / *if (p instanceof Uncle) {
            System.out.println("p instanceof Uncle");
        } else {
            Ststem.out.println("p not instanceof Uncle");
        } * /
        if (full instanceof String) {
            System.out.println("null instanceof String");
        } else {
            System.out.println("null not instanceof String");
        }
    }
}

输出结果如图所示,如果去掉注释符“/* ··· */”,编译会出问题。
在这里插入图片描述
注意:如果对比较结果取反,必须加()号,如本例的if(!(p1 instanceof Pare))。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值