Java 实验8 《抽象类与接口》

一、实验内容

1. 设计一个扩展自抽象类GeometriObject的新的Triangle类。绘制Triangle类和GeometricObject类的UML图并实现Triangle类。编写一个测试程序,提示用户输入三角形的三条边、一种颜色以及一个表明该三角形是否填充的布尔值。程序应该根据用户的输入,使用这些边以及颜色和是否填充的信息,创建一个Triangle对象。程序应该显示面积、周长、颜色以及真或者假来表明是否被填充。 

2. 创建名为ComparableCircle的类,它继承自Circle类,并实现Comparable接口。画出UML图并实现compareTo方法,使其根据面积比较两个圆。编写一个测试程序求出ComparableCircle对象的两个实例中的较大者。

3. 设计一个名为Colorable的接口,其中有名为howToColor()的void方法。可着色对象的每个类必须实现Colorable接口。设计一个扩展GeometricObject类并实现Colorable接口的名为Square的类。实现howToColor方法,显示消息“给所有的四条边着色”。画出包含Colorable、Square和GeometricObject的UML图。编写一个测试程序,创建有五个GeometricObject对象的数组。对于数组中的每个对象而言,如果对象是可着色的,那就调用howToColor方法。

二、实验分析与结果

1.1 UML图

1.2 运行结果

测试案例1:

测试案例2:

测试案例3:

1.3 实验分析

首先定义GeometricObject为从抽象类,同时在GeometricObject中定义两个抽象方法。

public abstract class GeometricObject
public abstract double getArea();
public abstract double getPerimeter();

由于抽象类无法实例化,所以抽象类必须继承,本题中是由Triangle类来继承GeometricObject类

class Triangle extends GeometricObject

注意抽象类被继承后,类中的抽象方法必须被重写,否则编译器会报错。

@Override
    public double getArea(){
        if(side1+side2-side3<Math.pow(10,-6) || side1+side3-side2<Math.pow(10,-6)
                || side2+side3-side1<Math.pow(10,-6)){
            return 0.0;
        }
        else {
            double s = (side1 + side2 + side3) / 2;
            double ans = Math.sqrt(s * (s - side1) * (s - side2) * (s - side3));
            return ans;
        }
    }

@Override
    public double getPerimeter() {
        return side1 + side2 +side3 ;
    }

最后在写一个Test.java测试文件来对写的抽象类和继承类进行测试。

在输入过程中,用户输入的三条边未必能构成三角形,在这里我采取的处理方法是用异常中的try-catch类提醒用户输入正确的三边。

while(flag)
{
    try{
        side1 = input.nextDouble();
        side2 = input.nextDouble();
        side3 = input.nextDouble();
        if(side1<side2+side3 && side2<side3+side1 && side3<side1+side2)
            flag = false;
        else
            throw new InputMismatchException();
    }
    catch(InputMismatchException exception){
        System.out.println("您输入的三条边构不成三角形,请重新输入:");
    }
}

这里throw的异常是我设置的是InputMismatchException,当然也可以不用try-catch来处理,直接简单的if-else也可以,只是程序会直接结束运行。

2.1 UML图

2.2 运行结果

测试案例1:

测试案例2:

2.3 实验分析 

在ComparableCircle类中继承Circle类并实现Comparable接口

class ComparableCircle extends Circle implements Comparable

在Comparable接口中,我们设置一个抽象方法compareTo

public abstract void compareTo(ComparableCircle circle2);

此处的public 和 abstract可以省略,接口默认方法是公共的抽象方法 

然后在ComparableCircle类中进行对接口中抽象方法的重写

@Override
    public void compareTo(ComparableCircle circle2){
        if(circle2.radius<this.radius) {
            System.out.println("第一个圆面积较大,较大圆半径为:" + this.radius);
            System.out.println("其面积为" + String.format("%." +
                    "3f",this.getArea()));
        }
        else {
            System.out.println("第二个圆面积较大,较大圆半径为:" + circle2.radius);
            System.out.println("其面积为" + String.format("%." +
                    "3f",circle2.getArea()));
        }
    }

  此处对要输出的圆的面积进行了保留三位小数的处理

  最后在创建一个Test.java文件对上述两个类和接口进行测试

3.1 UML图

3.2 实验结果

测试案例:

输出结果:

3.3 实验分析

本题中的GeometricObject可以直接使用第一题的代码,为了减少不必要的代码,我去掉了第一题中的两个抽象方法。

接口同样也是同第二题定义一个抽象方法。

public abstract void howToColor();

最后在Square类中实现这个抽象方法。

@Override
    public void howToColor() {
        System.out.println("给所有的四条边着色");
    }

题目中要求我们判断是否可以涂色,所以我在数组中定义了五个不同类的对象(有些类是前面实验用到的),并用instanceof关键字来判断其是否为实现Colorable接口的类。注意,此处题目要求要定义有五个GeometricObject对象的数组,这里就需要掌握Java中的方法匹配与绑定机制。Java中匹配方法的签名和绑定方法的实现是两个独立的事情。引用变量的声明类型决定了编译时匹配哪个方法。编译器会在编译时,根据参数类型、参数个数和参数顺序找到匹配的方法。一个方法可能在几个子类中都被实现。Java虚拟机在运行时动态绑定方法的实现,这是由变量的实际类型决定的。

GeometricObject[] geometricObject = {new Square(),new Rectangle(),new Circle(),
                new Triangle(),new Square()};
for(int i=0;i<5;i++){
    System.out.println("第" + (i+1) + "个对象");
    if(geometricObject[i] instanceof Colorable)
        ((Square)geometricObject[i]).howToColor();
    else
        System.out.println("不可着色");
}

三、源代码

T1:

  GeometricObject.java

public abstract class GeometricObject {
    private String color;
    private boolean filled;
    private java.util.Date dataCreated;

    protected GeometricObject(){
        dataCreated = new java.util.Date();
    }

    protected GeometricObject(String color,boolean filled){
        dataCreated = new java.util.Date();
        this.color = color;
        this.filled = filled;
    }

    public String getColor(){
        return color;
    }
    public void setColor(String color){
        this.color = color;
    }

    public boolean isFilled(){
        return filled;
    }
    public void setFilled(boolean filled){
        this.filled = filled;
    }

    public java.util.Date getDataCreated(){
        return dataCreated;
    }

    public String toString(){
        return "created on "+ dataCreated + "\ncolor: " + color +
                " and filled: " + filled;
    }

    public abstract double getArea();
    public abstract double getPerimeter();
}

  Triangle.java

class Triangle extends GeometricObject{
    double side1;
    double side2;
    double side3;

    public Triangle(){
    }

    public Triangle(double side1,double side2,double side3){
        this.side1 = side1;
        this.side2 = side2;
        this.side3 = side3;
    }

    public void setSide1(double s1){
        side1 = s1;
    }
    public void setSide2(double s2){
        side2 = s2;
    }
    public void setSide3(double s3){
        side3 = s3;
    }
    public double getSide1(){
        return side1;
    }
    public double getSide2(){
        return side2;
    }
    public double getSide3(){
        return side3;
    }

    @Override
    public double getArea(){
        if(side1+side2-side3<Math.pow(10,-6) || side1+side3-side2<Math.pow(10,-6)
                || side2+side3-side1<Math.pow(10,-6)){
            return 0.0;
        }
        else {
            double s = (side1 + side2 + side3) / 2;
            double ans = Math.sqrt(s * (s - side1) * (s - side2) * (s - side3));
            return ans;
        }
    }

    @Override
    public double getPerimeter() {
        return side1 + side2 +side3 ;
    }
}

  Test.java

import java.util.Scanner;
public class Test {
    public static void main(String []args) {
        double side1 = 0;
        double side2 = 0;
        double side3 = 0;

        System.out.println("请输入三角形三条边:");
        Scanner input = new Scanner(System.in);
        boolean flag = true;
        while(flag){
            try{
                side1 = input.nextDouble();
                side2 = input.nextDouble();
                side3 = input.nextDouble();
                if(side1<side2+side3 && side2<side3+side1 && side3<side1+side2)
                    flag = false;
                else
                    throw new ArrayIndexOutOfBoundsException();
            }
            catch(ArrayIndexOutOfBoundsException exception){
                System.out.println("你输入的三条边构不成三角形,请重新输入:");
            }
        }

        System.out.println("请输入填充的颜色");
        String color = input.next();

        System.out.println("请输入填充状态(0表示false,1表示true)");
        boolean flag1 = true;
        boolean isFilled = false;
        while(flag1){
            try {
                int intFilled = input.nextInt();
                if (intFilled == 0 || intFilled == 1) {
                    flag1 = false;
                    if (intFilled == 1)
                        isFilled = true;
                    else
                        isFilled = false;
                } else {
                    throw new ArrayIndexOutOfBoundsException();
                }
            }
            catch(ArrayIndexOutOfBoundsException exception){
                System.out.println("您输入的格式有误,请按照提示重新输入:");
            }
        }

        Triangle triangle = new Triangle(side1,side2,side3);
        triangle.setColor(color);
        triangle.setFilled(isFilled);

        System.out.println("该三角形面积为:" + String.format("%." +
                "3f",triangle.getArea()));
        System.out.println("该三角形周长为:" + triangle.getPerimeter());
        System.out.println("该三角形颜色为:" + triangle.getColor());
        System.out.println("该三角形填充状态为:" + triangle.isFilled());
    }
}

T2:

  Circle.java

public class Circle {
    public static final double PI = 3.14;
    public double radius;
    protected Circle(){}
    protected Circle(double radius){
        this.radius = radius;
    }

    public double getRadius(){
        return this.radius;
    }

    public void setRadius(double radius){
        this.radius = radius;
    }

    public double getArea(){
        return PI*this.radius*this.radius;
    }

    public double getPerimeter(){
        return 2*PI*this.radius;
    }
}

  Comparable接口和ComparableCircle类

class ComparableCircle extends Circle implements Comparable{
    Circle c1;
    ComparableCircle(){}

    @Override
    public void compareTo(ComparableCircle circle2){
        if(circle2.radius<this.radius) {
            System.out.println("第一个圆面积较大,较大圆半径为:" + this.radius);
            System.out.println("其面积为" + String.format("%." +
                    "3f",this.getArea()));
        }
        else {
            System.out.println("第二个圆面积较大,较大圆半径为:" + circle2.radius);
            System.out.println("其面积为" + String.format("%." +
                    "3f",circle2.getArea()));
        }
    }
}

interface Comparable{
    public abstract void compareTo(ComparableCircle circle2);
}

  Test.java

import java.util.Scanner;
public class Test {
    public static void main(String []args){
        Scanner input = new Scanner(System.in);
        System.out.println("请输入两个圆的半径");
        double radius1 = input.nextDouble();
        double radius2 = input.nextDouble();

        ComparableCircle c1 = new ComparableCircle();
        ComparableCircle c2 = new ComparableCircle();

        c1.setRadius(radius1);
        c2.setRadius(radius2);

        c1.compareTo(c2);
    }
}

T3:

  GeometricObject类

public abstract class GeometricObject {
    private String color;
    private boolean filled;
    private java.util.Date dataCreated;

    protected GeometricObject() {
        dataCreated = new java.util.Date();
    }

    protected GeometricObject(String color, boolean filled) {
        dataCreated = new java.util.Date();
        this.color = color;
        this.filled = filled;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public boolean isFilled() {
        return filled;
    }

    public void setFilled(boolean filled) {
        this.filled = filled;
    }

    public java.util.Date getDataCreated() {
        return dataCreated;
    }

    public String toString() {
        return "created on " + dataCreated + "\ncolor: " + color +
                " and filled: " + filled;
    }
}

  Colorable接口和Square类

public class Square extends GeometricObject implements Colorable{

    Square(){}
    @Override
    public void howToColor() {
        System.out.println("给所有的四条边着色");
    }
}

interface Colorable {
    public abstract void howToColor();
}

Test.java

public class Test {
    public static void main(String []args){
        GeometricObject[] geometricObject = {new Square(),new Rectangle(),new Circle(),
                new Triangle(),new Square()};
        for(int i=0;i<5;i++){
            System.out.println("第" + (i+1) + "个对象");
            if(geometricObject[i] instanceof Colorable)
                ((Square)geometricObject[i]).howToColor();
            else
                System.out.println("不可着色");
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值