用两个类对分数进行算术运算的java程序

fiei3ece  于 2021-07-12  发布在  Java
关注(0)|答案(3)|浏览(358)

所以我是一个编程初学者,我在编程课上遇到了一些问题。任务是使用两个类创建一个java程序,这两个类可以对分数执行算术运算。我认为我的主要问题是我需要在这个项目中使用的面向对象的概念,比如类和对象。我仍然对构造函数、访问器、变异器等的工作方式感到困惑。
第一个类fraction.java包含所有算术运算的方法定义,以及查找最大公分母、减少分数和打印结果的方法。我已经创建了printfraction、reducefraction、gcd和addfraction方法,但是还没有尝试过减法、乘法或除法。
第二个类testfraction.java旨在实现fraction类并测试其功能。我已经在这个类中编写了一些代码,在我还在工作的时候测试fraction类,并且我的方法(print、reduce和gcd)似乎在addfraction类之外工作。它看起来像是打印了一个内存地址什么的,而不是我要找的分数。我知道为什么,但不知道怎么修。
这是我目前的密码。正如我所说,我是一个初学者,我相信这不是很好,但我最担心的是完成和得到程序的工作。如果你有什么建议,请尽量让我明白。下面是一个示例输出:示例输出
分数.java:

public class Fraction {
    private int numerator;
    private int denominator;

    //no-arg constructor
    Fraction() {
        numerator = 0;
        denominator = 1;
    }

    //constructor
    Fraction(int numerator, int denominator) {
        this.numerator = numerator;
        this.denominator = denominator;
    }

    //accessor for numerator
    int getNumerator() {
        return numerator;
    }

    //mutator for numerator
    void setNumerator(int num) {
        numerator = num;
    }

    //accessor for denominator
    int getDenominator() {
        return denominator;
    }

    //mutator for denominator
    void setDenominator(int denom) {
        denominator = denom;
    }

    //printFraction method concatenates the numerator and denominator with a "/" string between them
    static void printFraction(int numerator, int denominator) {
        System.out.print(numerator + "/" + denominator);
    }

    //reduceFraction method uses the gcd method to print a reduced version of the fraction given
    public static void reduceFraction(int numerator, int denominator) {
        int smaller;
        if (numerator < denominator) {
            smaller = numerator;
        }
        else {
            smaller = denominator;
        }
        for (int i = smaller; i > 0; --i) {
            if (numerator % i == 0 && denominator % i == 0) {
                System.out.print("Reduced form: " + (numerator/gcd(numerator, denominator)) + "/" + (denominator/gcd(numerator, denominator)));
                break;
            }
        }
    }

    //recursive method that calls itself until it reduces completely to the gcd
    public static int gcd(int numerator, int denominator) {
        if (numerator % denominator == 0) {
            return denominator;
        }
        return gcd(denominator, numerator % denominator);
    }

    public static Fraction addFraction(Fraction a, Fraction b) {
        return new Fraction((a.numerator * b.denominator + a.denominator * b.numerator), (a.denominator * b.denominator));
    }

java(非常不完整,目前只包含基本测试):

import java.util.Scanner;
public class TestFraction {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        System.out.print("Enter the first fraction's numerator and denominator separated by spaces: ");
        Fraction myFraction1 = new Fraction(input.nextInt(), input.nextInt());
        System.out.print("Enter the second fraction's numerator and denominator separated by spaces: ");
        Fraction myFraction2 = new Fraction(input.nextInt(), input.nextInt());

        Fraction.printFraction(myFraction1.getNumerator(), myFraction1.getDenominator());
        System.out.println();
        Fraction.printFraction(myFraction2.getNumerator(), myFraction2.getDenominator());
        System.out.println();

        System.out.print(Fraction.gcd(myFraction1.getNumerator(), myFraction1.getDenominator()));
        System.out.println();
        System.out.print(Fraction.gcd(myFraction2.getNumerator(), myFraction2.getDenominator()));
        System.out.println();

        Fraction.reduceFraction(myFraction1.getNumerator(), myFraction1.getDenominator());

        System.out.println();
        System.out.println(Fraction.addFraction(myFraction1, myFraction2));
    }
}
gv8xihay

gv8xihay1#

以下是一些建议:
使您的类不可变(即,没有setter/mutator,2个变量应该是final)。允许像这样的“value”类改变并没有什么好的理由,它会使事情简化很多,因为在构建对象之后,您不需要担心事情的改变。它也符合所有 Number JavaAPI中的类—它们都不允许您在构造之后更改值。
通过抛出异常来处理构造函数中的零分母-这样您就不必在其他任何地方担心这种情况
在构造函数中处理负分数。最简单的方法是始终以分母为正结束构造函数。这样你就不会得到像“3/-4”这样奇怪的分数字符串
添加 Fraction.UNIT 以及 Fraction.ZERO 常量
添加 equals (和 hashCode )方法-你想要的 new Fraction(1, 1).equals(new Fraction(1, 1)) 返回 true 现在它会回来 false 如果希望所有分数都简化为最简单的形式,还可以在构造函数中处理简化为最简单的形式。
如果你想处理的分数不是最简单的形式,那么让 reduce 一种方法 Fraction . 没有理由让这成为一个公共静态
有一个 negate 只切换分子符号的方法
有一个 inverse 只需切换分母和分子的方法
那么 substract 可能只是 negate 以及 add 以及 divide 可以是 inverse 以及 multiply 使用 toString 转换为 String 最后一个建议是学习使用junit和(imo)assertj,编写自定义Assert和在测试计算中创建新分数的方法。然后你会得到更自然的测试用例,比如:

assertThat(fraction(2, 4)).isEqualTo(fraction(1, 2));
assertThat(fraction(1, 7).negate()).isEqualTo(fraction(-1, 7));
assertThat(fraction(4, 16)).hasNumerator(1).hasDenominator(4);
assertThatExceptionOfType(ArithmeticException.class)
    .isThrownBy(() -> fraction(1, 0));

这将使失败的测试更容易理解错误消息。
理想情况下,您应该有许多这样的测试,表明您的算法在所有需要处理的奇怪边缘情况下都能工作。

hyrbngr7

hyrbngr72#

您正在尝试系统输出打印对象。要解决这个问题,可以在fraction类中编写一个tostring()函数,如下所示
像现在一样打印结果

public string toString(){
    return this.numerator+'/'+ this.denominator;

}
gt0wga4j

gt0wga4j3#

欢迎使用stackoverflow。
你在打电话给警察 addFraction ,这是一个返回类型为的对象的方法 Fraction . 在java对象上调用println时,它返回对象的 toString() 方法。默认情况下,这个方法是“隐藏”的,并将返回对象的哈希代码(您看到的奇怪数字)。
以下是解决此问题的几个选项:
a) 覆盖 toString() 方法。只需在 Fraction 班级:

@Override
public String toString() {
    return "numerator=" + numerator + ", denominator=" + denominator + "]";
}

b) 而是打印对象的属性。将最后一行println替换为以下内容:

Fraction fraction = Fraction.addFraction(myFraction1, myFraction2);
System.out.println( String.format("numerator=%d, denominator=%d", fraction.getNumerator(), fraction.getDenominator()) );

花点时间来理解@sprint解释的概念,因为它将帮助您在将来编写更好的代码。祝你好运!

相关问题