题目要求
仿照BigDecimal类以面向对象的方式设计有理数类。
给出完整的有理数类的代码。
给出你的测试代码
要在不同包的其他类中调用有理数类。
- 注意:类名、变量名命名需符合Java规范。
源代码
package Rational;
public class RationalNum {
private int molecule;
private int denominator;
public RationalNum(int molecule,int denominator) {
this.molecule = molecule;
this.denominator = denominator;
if(this.denominator==0) { //分母为0时需要强制退出;
throw new IllegalArgumentException("分母不可为0!");
}
}
public int getNumerator() {
return molecule;
}
public void setNumerator(int molecule) {
this.molecule = molecule;
}
public int getDenominator() {
return denominator;
}
public void setDenominator(int denominator) {
this.denominator = denominator;
}
public int gcd() { // 约分
int t, m, n;
m = this.denominator;
n = this.molecule;
if (n == 0) {
return 0;
}
while (m % n != 0) {
t = n;
n = m % n;
m = t;
}
this.denominator /= n;
this.molecule /= n;
return n;
}
public RationalNum add(RationalNum num) { // 加法
int numerator, denominator;
denominator = num.denominator * this.denominator;
numerator = num.denominator * this.molecule + num.molecule * this.denominator;
RationalNum result = new RationalNum(numerator, denominator);
result.gcd();
return result;
}
public RationalNum subtraction(RationalNum num) { // 减法
int numerator, denominator;
denominator = num.denominator * this.denominator;
numerator = this.molecule * num.denominator - num.molecule * this.denominator;
RationalNum result = new RationalNum(numerator, denominator);
result.gcd();
return result;
}
public RationalNum multiply(RationalNum num) { // 乘法
int numerator = this.molecule * num.molecule;
int denominator = this.denominator * num.denominator;
RationalNum result = new RationalNum(numerator, denominator);
result.gcd();
return result;
}
public RationalNum division(RationalNum num) { // 除法
if (num.molecule != 0) {
int denominator = this.denominator * num.molecule;
int numerator = this.molecule * num.denominator;
RationalNum result = new RationalNum(numerator, denominator);
result.gcd();
return result;
} else
throw new IllegalArgumentException("除数不可为0!");
}
public RationalNum abs() { // 绝对值
int d,m;
if (this.denominator < 0) d = -this.denominator;
else d = this.denominator;
if (this.molecule < 0) m = -this.molecule;
else m = this.molecule;
RationalNum result = new RationalNum(m, d);
return result;
}
public boolean equals(RationalNum num) { //是否相等;
RationalNum temp1 = new RationalNum(this.molecule, this.denominator);
RationalNum temp2 = new RationalNum(num.molecule, num.denominator);
temp1.gcd();
temp2.gcd();
if (temp1.denominator == temp2.denominator && temp1.molecule == temp2.molecule) return true;
else return false;
}
public double doubleValue() {
return (double) this.molecule / this.denominator;
}
public int intValue() {
return this.molecule / this.denominator;
}
public String toString() {
if(this.molecule==0)return 0+"";
else if(this.denominator==1)return this.molecule+"";
else if(this.denominator==-1)return "-"+this.molecule;
else return this.molecule + "/" + this.denominator;
}
}
测试样例
import java.util.Scanner;
public class Main {
public static void main(String args[]) {
Scanner in=new Scanner(System.in);
System.out.println("请输入两个有理数的分子和分母:");
RationalNum x = new RationalNum(in.nextInt(), in.nextInt());
RationalNum y = new RationalNum(in.nextInt(), in.nextInt());
System.out.println("|x| = " + x.abs());
System.out.println("x = " + x);
System.out.println("y = " + y);
System.out.println("x + y = " + x.add(y));
System.out.println("x - y = " + x.subtraction(y));
System.out.println("x * y = " + x.multiply(y));
System.out.println("x / y = " + x.division(y));
System.out.println("x的int 型 " + x.intValue());
System.out.println("x的double 型 " + x.doubleValue());
in.close();
}
}
提出问题
-
与c语言的有理数代码相比较,为什么你设计的类更加面向对象?
c语言更偏于面向过程,着重强调运算过程,而Java则是面向对象,对于对象进行一系列操作,编写类,方便对象使用。 -
尝试从代码复用的角度来描述你设计的有理数类
1.别人如何复用你的代码
直接把代码发给别人,或者打包成.jar供别人使用
2.别人的代码是否依赖你的有理数类的内部属性?当你的有理数类的属性修改时,是否会影响他人调用你有理数类的代码?
依赖于有理数内部属性,因为代码并不没有面向所有情况而写,有理数的输入是有一定条件的;
属性修改后,可能是另一种计算情况。
3.有理数类的public方法是否设置合适?为什么有的方法设置为private?
设置为public,就是为了方便其他包使用;
设置为private是为了实现数据封装,不让别人用或者修改你的数据,比较安全。
马克-to-win:我并不知道未来外部别人怎么用我们的接口,所以尽量少给别人设置障碍(少添点堵),就设置权限为public,出于这种考虑,Sun公司一开始就规定,接口属性和方法默认就为public。