有理数类的设计

仿照BigDecimal类以面向对象的方式设计有理数类。

有理数代码:

1、有理数类源代码:

public class Rational {
//属性

private long numerator = 0; //分子

private long denominator = 1; //分母

public long getNumerator() {
return numerator;

}

public void setNumerator(long numerator) {
this.numerator = numerator;

}

public long getDenominator() {
return denominator;

}

public void setDenominator(long denominator) {
this.denominator = denominator;

}

//构造函数(无参)

public Rational(){//分子分母初始化

this.numerator = 0;

this.denominator = 1;

}

//构造函数(有参)

public Rational(long numerator, long denominator){
this.numerator = numerator/gcd(Math.abs(numerator), Math.abs(denominator)); //分子化简(除以分子、分母的最大公约数)

this.denominator = denominator/gcd(Math.abs(numerator), Math.abs(denominator));//分母化简(除以分子、分母的最大公约数)

}

public static long gcd (long number1, long number2){//最大公约数计算

while (number1 != number2)

{
if (number1 > number2)

number1 = number1 - number2;

else

number2 = number2 - number1;

}

return number1;

}

public static Rational add (Rational num1, Rational num2) {//有理数求和

long tempNumerator = num1.numerator*num2.denominator + num1.denominator*num2.numerator;

long tempDenominator = num1.denominator*num2.denominator;

long gcd = gcd(Math.abs(tempNumerator),Math.abs(tempDenominator));

Rational rationalNumber = new Rational(tempNumerator/gcd,tempDenominator/gcd);

return rationalNumber;

}

public static Rational subtract (Rational num1, Rational num2) {//有理数求差

long tempNumerator = num1.numerator*num2.denominator - num1.denominator*num2.numerator;

long tempDenominator = num1.denominator*num2.denominator;

long gcd = gcd(Math.abs(tempNumerator),Math.abs(tempDenominator));

Rational rationalNumber = new Rational(tempNumerator/gcd,tempDenominator/gcd);

return rationalNumber;

}

public static Rational multiply (Rational num1, Rational num2) {//有理数求积

long tempNumerator = num1.numerator*num2.numerator;

long tempDenominator = num1.denominator*num2.denominator;

long gcd = gcd(Math.abs(tempNumerator),Math.abs(tempDenominator));

Rational rationalNumber = new Rational(tempNumerator/gcd,tempDenominator/gcd);

return rationalNumber;

}

public static Rational divide (Rational num1, Rational num2) {//有理数求商

long tempNumerator = num1.numerator*num2.denominator;

long tempDenominator = num1.denominator*num2.numerator;

long gcd = gcd(Math.abs(tempNumerator),Math.abs(tempDenominator));

Rational rationalNumber = new Rational(tempNumerator/gcd,tempDenominator/gcd);

return rationalNumber;

}

}

测试代码: 

2、测试代码:

(在RationalTest.java中测试Rational.java)

//import java.util.Scanner;

public class RationalTest {
/*Scanner scanner = new Scanner(System.in);

int number = scanner.nextInt();

int nextNumber = scanner.nextInt();

*/

private static Rational num1=new Rational(1,2); //第一个分数

private static Rational num2=new Rational(12,4); //第二个分数

private static double test = Double.parseDouble("3457367536")/(double)6769656;

public static void main(String[] args) {
//加法测试

Rational result=Rational.add(num1, num2);

System.out.println("有理数求和:");

System.out.println("(分数形式):1/2+12/4="+result.getNumerator()+"/"+result.getDenominator());

System.out.println("(小数形式):1/2+12/4="+(result.getNumerator()/(double)result.getDenominator()));

//减法测试

result=Rational.subtract(num1, num2);

System.out.println("有理数求差:");

System.out.println("(分数形式):1/2-12/4="+result.getNumerator()+"/"+result.getDenominator());

System.out.println("(小数形式):1/2-12/4="+(result.getNumerator()/(double)result.getDenominator()));

//乘法测试

result=Rational.multiply(num1, num2);

System.out.println("有理数求积:");

System.out.println("(分数形式):1/2*12/4="+result.getNumerator()+"/"+result.getDenominator());

System.out.println("(小数形式):1/2*12/4="+(result.getNumerator()/(double)result.getDenominator()));

//除法测试

result=Rational.divide(num1, num2);

System.out.println("有理数求商:");

System.out.println("(分数形式):1/2-12/4="+result.getNumerator()+"/"+result.getDenominator());

System.out.println("(小数形式):1/2*12/4="+(result.getNumerator()/(double)result.getDenominator()));

}

}

Q:尝试回答与c语言的有理数代码相比较,为什么你设计的类更加面向对象?

A:C语言是面向过程的编程,栗子:把大象放入冰箱。这个过程的步骤:打开冰箱,把大象放入冰箱,关冰箱门。C语言就是将这三个步骤封装成三个函数来解决问题。而在JAVA中,这里就有两个对象:冰箱和门。每个对象对应的步骤就封装成方法来解决问题。类是对象的蓝图,有了类,才能设计一系列对象并设计一系列方法来解决。

Q: 尝试从代码复用的角度来描述你设计的有理数类。从几个方面讨论。

别人如何复用你的代码?

A:下载包,并导入,通过包内的方法解决问题。

别人的代码是否依赖你的有理数类的内部属性?当你的有理数类的属性修改时,是否会影响他人调用你有理数类的代码?

A:具有依赖我的有理数类的内部属性,当有理数类的属性修改时,会影响调用有理数类的代码。

有理数类的public方法是否设置合适?为什么有的方法设置为private?

A:有理数类的public方法设置合适,设置为public就有公共访问的权限。当有的方法不需要被其他调用时,就可以设置成private,仅供内部调用。

你的类里面有static属性或方法吗?如果有,为什么要设置为static的?

A:有static方法;在创建类中有多个对象时,用static修饰的方法无需创建对象,可以直接调用。这样比较方便。

上一篇:63. 搜索旋转排序数组 II(回顾)


下一篇:《Effective C++》学习笔记(条款24:若所有参数皆需类型转换,请使用非成员函数)