厦大计算机系Java程序设计实验(四)

习题1 正八边形类

题目描述:写一个正八边形类Octagon,要求从课本的GeometricObject类继承,并实现 Comparable和 Cloneable接口。写一个测试类,测试Octagon类的所有可用方法。

解题思路:首先在Octagon类内实现GeometricObject类中的getArea()和getPerimeter()方法,然后覆盖clone和compareTo这两个方法。在测试类中进行相应的测试。

源代码

import java.util.Date;

abstract class GeometricObject
{
    private String color = "white";
    private boolean filled = false;
    private Date dateCreated;
    
    protected GeometricObject()
    {
        this.dateCreated = new Date();
    }
    
    protected GeometricObject(String color, boolean filled)
    {
        this.dateCreated = new Date();
        this.color = color;
        this.filled = filled;
    }
    
    public String getColor()
    {
        return this.color;
    }
    
    public void setColor(String color)
    {
        this.color = color;
    }
    
    public boolean isFilled()
    {
        return this.filled;
    }
    
    public void setFilled(boolean filled)
    {
        this.filled = filled;
    }
    
    public Date getDateCreated()
    {
        return this.dateCreated;
    }
    
    @Override
    public String toString()
    {
        return "created on " + dateCreated + "\ncolor: " + color +
                " and filled: " + filled;
    }
    
    public abstract double getArea();
    
    public abstract double getPerimeter();
}

class Octagon extends GeometricObject implements Comparable, Cloneable
{
    double side;
    
    public Octagon()
    {
        
    }
    
    public Octagon(double side)
    {
        this.side = side;
    }
    
    public Octagon(double side, String color, boolean filled)
    {
        this.side = side;
        setColor(color);
        setFilled(filled);
    }
    
    public double getSide()
    {
        return side;
    }
    
    public void setSide(double side)
    {
        this.side = side;
    }
    
    @Override
    public double getArea()
    {
        return (2 + 4 / Math.sqrt(2)) * side * side;
    }
    
    @Override
    public double getPerimeter()
    {
        return 8 * side;
    }
    
    @Override
    public Object clone() throws CloneNotSupportedException
    {
        return super.clone();
    }
    
    @Override
    public int compareTo(Object o)
    {
        if(this.side > ((Octagon)o).side)
            return 1;
        else if(this.side < ((Octagon)o).side)
            return -1;
        else
            return 0;
    }
    
}

public class Test
{
    public static void main(String[] args)
    {
        Octagon o = new Octagon(5);
        
        System.out.println("Area: " + o.getArea());
        System.out.println("Perimeter: " + o.getPerimeter());
        
        Octagon o1 = new Octagon();
        try
        {
            o1 = (Octagon)o.clone();
        }
        catch(CloneNotSupportedException ex)
        {
            System.out.println("CloneNotSupportedException");
        }
        
        System.out.println(o.compareTo(o1));
    }
}

测试样例

构建一个边长为5的正八边形,计算其面积和周长,并克隆一个对象,比较两个对象。具体结果如下:

Area: 120.71067811865476
Perimeter: 40.0
0

习题2 MyRational

题目描述:改写课本Listing 13.13的分数类Rational,将分子和分母从类型long改为BigInteger,新版分数类名为MyRational。写一个测试类,测试MyRational。

解题思路:将课本上的源代码中的long类型数据全部换成BigInteger,同时使用BigInteger的静态方法进行四则运算。

源代码

import java.math.BigInteger;

public class MyRational extends Number implements Comparable
{
    private BigInteger numerator = new BigInteger("0");
    private BigInteger denominator = new BigInteger("1");
    
    public MyRational()
    {
        this(new BigInteger("0"), new BigInteger("1"));
    }
    
    public MyRational(BigInteger numerator, BigInteger denominator)
    {
        BigInteger gcd = gcd(numerator, denominator);
        this.numerator = ((new BigInteger(denominator.compareTo(BigInteger.ZERO) + "")).multiply(numerator)).divide(gcd);
        this.denominator = denominator.abs().divide(gcd);
    }
    
    private static BigInteger gcd(BigInteger n, BigInteger d)
    {
        BigInteger n1 = n.abs();
        BigInteger n2 = d.abs();
        BigInteger gcd = BigInteger.ONE;
        
        for(BigInteger k = BigInteger.ONE; k.compareTo(n1) <= 0 && k.compareTo(n2) <= 0; k = k.add(BigInteger.ONE))
        {
            if(n1.mod(k).compareTo(BigInteger.ZERO) == 0 && n2.mod(k).compareTo(BigInteger.ZERO) == 0)
                gcd = k;
        }
        
        return gcd;
    }
    
    public BigInteger getNumerator()
    {
        return numerator;
    }
    
    public BigInteger getDenominator()
    {
        return denominator;
    }
    
    public MyRational add(MyRational secondRational)
    {
        BigInteger n = numerator.multiply(secondRational.getDenominator()).add(
                denominator.multiply(secondRational.getNumerator()));
        BigInteger d = denominator.multiply(secondRational.getDenominator());
        return new MyRational(n, d);
    }
    
    public MyRational subtract(MyRational secondRational)
    {
        BigInteger n = numerator.multiply(secondRational.getDenominator()).subtract(
                denominator.multiply(secondRational.getNumerator()));
        BigInteger d = denominator.multiply(secondRational.getDenominator());
        return new MyRational(n, d);
    }
    
    public MyRational multiply(MyRational secondRational)
    {
        BigInteger n = numerator.multiply(secondRational.getNumerator());
        BigInteger d = denominator.multiply(secondRational.getDenominator());
        return new MyRational(n, d);
    }
    
    public MyRational divide(MyRational secondRational)
    {
        BigInteger n = numerator.multiply(secondRational.getDenominator());
        BigInteger d = denominator.multiply(secondRational.getNumerator());
        return new MyRational(n, d);
    }
    
    @Override
    public String toString()
    {
        if(denominator.compareTo(BigInteger.ONE) == 0)
            return numerator.toString() + "";
        else
            return numerator.toString() + "/" + denominator.toString();
    }
    
    @Override
    public boolean equals(Object parm1)
    {
        if((this.subtract((MyRational)(parm1))).getNumerator().compareTo(BigInteger.ZERO) == 0)
            return true;
        else
            return false;
    }
    
    @Override
    public int intValue()
    {
        return (int)doubleValue();
    }
    
    @Override
    public float floatValue()
    {
        return (float)doubleValue();
    }
    
    @Override
    public double doubleValue()
    {
        return numerator.doubleValue() * 1.0 / denominator.doubleValue();
    }
    
    @Override
    public long longValue()
    {
        return (long)doubleValue();
    }
    
    @Override
    public int compareTo(Object o)
    {
        if((this.subtract((MyRational)o)).getNumerator().compareTo(BigInteger.ZERO) == 1)
            return 1;
        else if((this.subtract((MyRational)o)).getNumerator().compareTo(BigInteger.ZERO) == -1)
            return -1;
        else
            return 0;
    }
}

测试类如下:

import java.math.BigInteger;

public class Test
{
    public static void main(String[] args)
    {
        BigInteger numerator = new BigInteger("1");
        BigInteger denominator = new BigInteger("12345");
        MyRational r1 = new MyRational(numerator, denominator);
        MyRational r2 = new MyRational(numerator, denominator);
        MyRational r3 = new MyRational(numerator, denominator);
        System.out.println("r1 + r2 + r3 = " + r1.add(r2).add(r3));
        System.out.println("r1 - r2 - r3 = " + r1.subtract(r2).subtract(r3));
        System.out.println("r1 * r2 * r3 = " + r1.multiply(r2).multiply(r3));
        System.out.println("r1 / r2 / r3 = " + r1.divide(r2).divide(r3));
    }
}

测试样例

按照测试类内的数据,输出的结果为:

r1 + r2 + r3 = 1/4115
r1 - r2 - r3 = -1/12345
r1 * r2 * r3 = 1/1881365963625
r1 / r2 / r3 = 12345

习题3  发扑克牌

题目描述:编程实现程序每次启动后,在界面上随机显示54张扑克牌中的4张,并在其下方显示花色名(如图)。扑克牌图片已打包到cards.jar文件中,命名规则见后。

厦大计算机系Java程序设计实验(四)_第1张图片

效果图

厦大计算机系Java程序设计实验(四)_第2张图片

扑克牌命名规则

解题思路:首先利用随机数,随机抽取四张不相同的扑克牌,然后从jar文件中打开相应的图片,并利用函数求出该扑克牌的名称,最后在窗口内予以显示。

源代码

import java.io.*;
import java.util.Random;
import java.util.jar.*;
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class DisplayFourCards extends Application
{
    public static ImageView readImageFromJar(String jarname, String picname)
    {
        ImageView imageView = null;
        try
        {
            JarFile jarFile = new JarFile(jarname);
            JarEntry entry = jarFile.getJarEntry(picname);
            InputStream in = jarFile.getInputStream(entry);
            imageView = new ImageView(new Image(in));
            in.close();
            jarFile.close();
        }
        catch (IOException e)
        {
            System.err.println("read file error.");
        }
        return imageView;
    }
    
    @Override
    public void start(Stage primaryStage)
    {
        BorderPane pane = new BorderPane();
        
        Random random = new Random((int)(System.currentTimeMillis()));
        int img1Number = random.nextInt(54) + 1;
        String img1Address = "cards/" + img1Number + ".png";
        
        int img2Number;
        do
        {
            img2Number = random.nextInt(54) + 1;
        }
        while(img2Number == img1Number);
        String img2Address = "cards/" + img2Number + ".png";
        
        int img3Number;
        do
        {
            img3Number = random.nextInt(54) + 1;
        }
        while(img3Number == img1Number || img3Number == img2Number);
        String img3Address = "cards/" + img3Number + ".png";
        
        int img4Number;
        do
        {
            img4Number = random.nextInt(54) + 1;
        }
        while(img4Number == img1Number || img4Number == img2Number || img4Number == img3Number);
        String img4Address = "cards/" + img4Number + ".png";
        
        ImageView img1View = readImageFromJar("D:\\NetBeansProjects\\testJavaFX\\src\\cards.jar", img1Address);
        ImageView img2View = readImageFromJar("D:\\NetBeansProjects\\testJavaFX\\src\\cards.jar", img2Address);
        ImageView img3View = readImageFromJar("D:\\NetBeansProjects\\testJavaFX\\src\\cards.jar", img3Address);
        ImageView img4View = readImageFromJar("D:\\NetBeansProjects\\testJavaFX\\src\\cards.jar", img4Address);
        
        String card1Name = getName(img1Number);
        String card2Name = getName(img2Number);
        String card3Name = getName(img3Number);
        String card4Name = getName(img4Number);
        
        Label label1 = new Label(card1Name);
        Label label2 = new Label(card2Name);
        Label label3 = new Label(card3Name);
        Label label4 = new Label(card4Name);
        
        GridPane.setHalignment(label1, HPos.CENTER);
        GridPane.setHalignment(label2, HPos.CENTER);
        GridPane.setHalignment(label3, HPos.CENTER);
        GridPane.setHalignment(label4, HPos.CENTER);
        
        GridPane grid = new GridPane();
        grid.setPadding(new Insets(5, 5, 5, 5));
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setAlignment(Pos.CENTER);
        grid.add(img1View, 0, 0);
        grid.add(img2View, 1, 0);
        grid.add(img3View, 2, 0);
        grid.add(img4View, 3, 0);
        grid.add(label1, 0, 1);
        grid.add(label2, 1, 1);
        grid.add(label3, 2, 1);
        grid.add(label4, 3, 1);
        pane.setCenter(grid);
        
        Scene scene = new Scene(pane, 400, 200);
        primaryStage.setTitle("Four Cards");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    
    public String getName(int number)
    {
        String name = "";
        
        switch((number - 1) / 13)
        {
            case 0: name = name + "黑桃"; break;
            case 1: name = name + "红心"; break;
            case 2: name = name + "方块"; break;
            case 3: name = name + "梅花"; break;
            default:
            {
                if(number == 53)
                    name = name + "小 王";
                else if(number == 54)
                    name = name + "大 王";
            }
        }
        
        if(1 <= number && number <= 52)
        {
            if((number - 1) % 13 == 0)
                name = name + "A";
            else if(1 <= (number - 1) % 13 && (number - 1) % 13 <= 9)
                name = name + ((number - 1) % 13 + 1) + "";
            else if((number - 1) % 13 == 10)
                name = name + "J";
            else if((number - 1) % 13 == 11)
                name = name + "Q";
            else
                name = name + "K";
        }
        
        return name;
    }
}

测试样例

输出效果为:

厦大计算机系Java程序设计实验(四)_第3张图片
厦大计算机系Java程序设计实验(四)_第4张图片
厦大计算机系Java程序设计实验(四)_第5张图片

习题4  我的计算器

题目描述:编程设计如图所示的界面。要求最后的界面布局尽可能接近效果图,不需要实现按钮功能。注意有几个按钮的背景色有所不同。

厦大计算机系Java程序设计实验(四)_第6张图片

解题思路:将窗口分为两部分,上半部分为文本域,下半部分为网格,分别利用函数实现,再进行拼装。

源代码

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class Calculator extends Application
{
    @Override
    public void start(Stage primaryStage)
    {
        BorderPane pane = new BorderPane();
        pane.setTop(getTextField());
        pane.setBottom(getGrid());
        
        Scene scene = new Scene(pane);
        primaryStage.setScene(scene);
        primaryStage.setTitle("计算器");
        primaryStage.setResizable(false);
        primaryStage.show();
    }
    
    private TextField getTextField()
    {
        TextField textField = new TextField("0");
        textField.setPadding(new Insets(30, 20, 5, 10));
        textField.setEditable(false); 
        textField.setAlignment(Pos.BOTTOM_RIGHT);
        textField.setStyle("-fx-font: 22 Consolas;");
        return textField;
    }
    
    private GridPane getGrid()
    {
        GridPane pane = new GridPane();
        pane.setAlignment(Pos.CENTER);
        pane.setHgap(5);
        pane.setVgap(5);
        pane.setPadding(new Insets(5, 0, 0, 10));
        
        Button b00 = new Button("MC");
        b00.setPrefSize(40, 20);
        pane.add(b00, 0, 0);
        
        Button b01 = new Button("MR");
        b01.setPrefSize(40, 20);
        pane.add(b01, 1, 0);
        
        Button b02 = new Button("MS");
        b02.setPrefSize(40, 20);
        pane.add(b02, 2, 0);
        
        Button b03 = new Button("M+");
        b03.setPrefSize(40, 20);
        pane.add(b03, 3, 0);
        
        Button b04 = new Button("M-");
        b04.setPrefSize(40, 20);
        pane.add(b04, 4, 0);
        
        Button b10 = new Button("←");
        b10.setPrefSize(40, 20);
        pane.add(b10, 0, 1);
        
        Button b11 = new Button("CE");
        b11.setPrefSize(40, 20);
        pane.add(b11, 1, 1);
        
        Button b12 = new Button("C");
        b12.setPrefSize(40, 20);
        pane.add(b12, 2, 1);
        
        Button b13 = new Button("±");
        b13.setPrefSize(40, 20);
        pane.add(b13, 3, 1);
        
        Button b14 = new Button("√");
        b14.setPrefSize(40, 20);
        pane.add(b14, 4, 1);
        
        Button b20 = new Button("7");
        b20.setPrefSize(40, 20);
        b20.setStyle("-fx-base: lightgray");
        pane.add(b20, 0, 2);
        
        Button b21 = new Button("8");
        b21.setStyle("-fx-base: lightgray");
        b21.setPrefSize(40, 20);
        pane.add(b21, 1, 2);
        
        Button b22 = new Button("9");
        b22.setPrefSize(40, 20);
        b22.setStyle("-fx-base: lightgray");
        pane.add(b22, 2, 2);
        
        Button b23 = new Button("/");
        b23.setPrefSize(40, 20);
        pane.add(b23, 3, 2);
        
        Button b24 = new Button("%");
        b24.setPrefSize(40, 20);
        pane.add(b24, 4, 2);
        
        Button b30 = new Button("4");
        b30.setPrefSize(40, 20);
        b30.setStyle("-fx-base: lightgray");
        pane.add(b30, 0, 3);
        
        Button b31 = new Button("5");
        b31.setPrefSize(40, 20);
        b31.setStyle("-fx-base: lightgray");
        pane.add(b31, 1, 3);
        
        Button b32 = new Button("6");
        b32.setPrefSize(40, 20);
        b32.setStyle("-fx-base: lightgray");
        pane.add(b32, 2, 3);
        
        Button b33 = new Button("*");
        b33.setPrefSize(40, 20);
        pane.add(b33, 3, 3);
        
        Button b34 = new Button("1/x");
        b34.setPrefSize(40, 20);
        pane.add(b34, 4, 3);
        
        Button b40 = new Button("1");
        b40.setPrefSize(40, 20);
        b40.setStyle("-fx-base: lightgray");
        pane.add(b40, 0, 4);
        
        Button b41 = new Button("2");
        b41.setPrefSize(40, 20);
        b41.setStyle("-fx-base: lightgray");
        pane.add(b41, 1, 4);
        
        Button b42 = new Button("3");
        b42.setPrefSize(40, 20);
        b42.setStyle("-fx-base: lightgray");
        pane.add(b42, 2, 4);
        
        Button b43 = new Button("-");
        b43.setPrefSize(40, 20);
        pane.add(b43, 3, 4);
        
        Button b44 = new Button("=");
        b44.setPrefSize(40, 50);
        GridPane.setValignment(b44, VPos.TOP);
        pane.add(b44, 4, 4, 4, 5);
        
        Button b50 = new Button("0");
        b50.setPrefSize(85, 20);
        GridPane.setValignment(b50, VPos.TOP);
        b50.setStyle("-fx-base: lightgray");
        pane.add(b50, 0, 5, 2, 5);
        
        Button b52 = new Button(".");
        b52.setPrefSize(40, 20);
        b52.setStyle("-fx-base: lightgray");
        pane.add(b52, 2, 5);
        
        Button b53 = new Button("+");
        b53.setPrefSize(40, 20);
        pane.add(b53, 3, 5);
        
        return pane;
    }
}

测试样例

效果如下:

厦大计算机系Java程序设计实验(四)_第7张图片

你可能感兴趣的:(Java)