仿照BigDecimal类以面向对象的方式设计有理数类。
完整的有理数类的代码。
package RationalNumber;
public class RationalNumber {//有理数类
private int numerator;
private int denominator;
private boolean isInt(String str) {//判断是否为int
int i = 0;
if (str.charAt(0) == '-')
i++;
for (; i < str.length(); i++) {
if (str.charAt(i) < '0' || str.charAt(i) > '9')
return false;
}
return true;
}
public RationalNumber(String str) {//构造方法
if (isInt(str)) {//整数
this.numerator = Integer.valueOf(str);
this.denominator = 1;
} else if (str.indexOf(".") != -1) {//小数
String str1 = str.substring(0, str.indexOf("."));
String str2 = str.substring(str.indexOf(".") + 1, str.length());
if (isInt(str1) && isInt(str2)) {
this.numerator = Integer.valueOf(str1);
this.denominator = Integer.valueOf(str2);
this.numerator = Integer.valueOf(str1 + str2);
this.denominator = (int) Math.pow(10, str2.length());
fractionReduction();
}
} else if (str.indexOf("/") != -1) {//分数
String str1 = str.substring(0, str.indexOf("/"));
String str2 = str.substring(str.indexOf("/") + 1, str.length());
if (isInt(str1) && isInt(str2)) {
this.numerator = Integer.valueOf(str1);
this.denominator = Integer.valueOf(str2);
if (this.denominator == 0)
System.out.print("分母不能为零");
else
fractionReduction();
}
} else {
System.out.print("输入错误");
}
}
public int gcd(int a, int b) {//最大公因数
if (b == 0)
return a;
return gcd(b, a % b);
}
public void fractionReduction() {//约分
int flag = 1;
if (this.numerator < 0) {
this.numerator *= -1;
flag *= -1;
}
if (this.denominator < 0) {
this.denominator *= -1;
flag *= -1;
}
int mgcd = gcd(this.numerator, this.denominator);
this.numerator = flag * this.numerator / mgcd;
this.denominator = this.denominator / mgcd;
}
public RationalNumber add(RationalNumber x) {//加
int numerator = this.numerator * x.denominator + this.denominator * x.numerator;
int denominator = this.denominator * x.denominator;
return new RationalNumber(numerator + "/" + denominator);
}
public RationalNumber subtract(RationalNumber x) {//减
int numerator = this.numerator * x.denominator - this.denominator * x.numerator;
int denominator = this.denominator * x.denominator;
return new RationalNumber(numerator + "/" + denominator);
}
public RationalNumber multply(RationalNumber x) {//乘
int numerator = this.numerator * x.numerator;
int denominator = this.denominator * x.denominator;
return new RationalNumber(numerator + "/" + denominator);
}
public RationalNumber divide(RationalNumber x) {//除
int numerator = this.numerator * x.denominator;
int denominator = this.denominator * x.numerator;
return new RationalNumber(numerator + "/" + denominator);
}
public String toString() {
if (this.denominator == 1) {
return this.numerator + "";
} else {
return this.numerator + "/" + this.denominator;
}
}
}
给出你的测试代码。要在与有理数类不同包的其他类中调用有理数类。
package RationalNumber;
public class Main {
public static void main(String[] args) {
int n = 4;
RationalNumber num[] = new RationalNumber[10];
num[0] = new RationalNumber("1");
num[1] = new RationalNumber("5/8");
num[1] = new RationalNumber("8/3");
num[2] = new RationalNumber("1.1");
num[3] = new RationalNumber("-1");
System.out.println("测试数据:");
for (int i = 0; i < n; i++) {
System.out.println("num[" + i + "]= " + num[i].toString());
}
System.out.println("加法");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.println(num[i].toString() + " + " + num[j].toString() + " = " + num[i].add(num[j]));
}
}
System.out.println("减法");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.println(num[i].toString() + " - " + num[j].toString() + " = " + num[i].subtract(num[j]));
}
}
System.out.println("乘法");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.println(num[i].toString() + " * " + num[j].toString() + " = " + num[i].multply(num[j]));
}
}
System.out.println("除法");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.println(num[i].toString() + " / " + num[j].toString() + " = " + num[i].divide(num[j]));
}
}
}
}
尝试回答与c语言的有理数代码相比较,为什么你设计的类更加面向对象?
c语言面向过程,java面向对象。面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。面向对象就是是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
尝试从代码复用的角度来描述你设计的有理数类。从几个方面讨论。
别人如何复用你的代码?
导入包中的有理数类,如:import java.util.Rational;
别人的代码是否依赖你的有理数类的内部属性?当你的有理数类的属性修改时,是否会影响他人调用你有理数类的代码?
别人的代码会依赖于我的有理数类的属性;当我的有理数类的属性修改时,不会影响他人调用我的有理数类的代码,因为设置成为private类型。
有理数类的public方法是否设置合适?为什么有的方法设置为private?
合适;因为public是公有的,private是私有的。public允许外部访问,private不允许,别的类就不能通过该private方法访问该变量,可以防止使用者不小心对数据修改造成程序错误。
你的类里面有static属性或方法吗?如果有,为什么要设置为static的?
没有,static方法修饰的成员不再属于某个对象,而是属于它所在的类。只需要通过其类名就可以访问,不需要再消耗资源反复创建对象。在类第一次加载的时候,static就已经在内存中了,直到程序结束后,该内存才会释放。
可选:简单说明你的设计的有理数类是否是不可变类?如果想要设计成不可变类,主要从哪几个方面着手?
不是,类使用final修饰符修饰,保证类不能被继承。