# Rational类的书写

## 1. 代码

1. Rational.java
package rational;

public class Rational extends Number implements Comparable<Rational>{
/**继承Number类提供将表示的数值转换为 byte、double、float、int、long 和 short 的方法。
*
*/

private long numerator=0;
private long denominator=1;

public Rational() throws Exception {
this(0,1);
}
public Rational(long numerator, long denominator)throws Exception  {
if(denominator == 0){

throw new Exception("/ by zero");
}//抛出异常
long gcd=gcd(numerator, denominator);
this.numerator =((denominator >0)?1:-1)*numerator /gcd;
this.denominator=Math.abs(denominator )/gcd ;

}

private static long gcd(long n, long d) {
long n1=Math.abs(n);
long n2=Math.abs(d);
long remainder = n1 % n2;
while (remainder != 0) {
n1 = n2;
n2 = remainder;
remainder = n1 % n2;
}
return n2;
}

/**
* 最大公约数
*/
public long getNumerator() {
return numerator ;
}
public long getDenominator () {
return denominator ;
}
public void setNumerator(long numerator) {
this.numerator = numerator;
}
public void setDenominator(long denominator) {
this.denominator = denominator;
}

public Rational add(Rational augend) throws Exception {
long n=numerator *augend.denominator+denominator *augend.numerator;
long d=denominator*augend .denominator ;
return new Rational(n,d);

}
/**
* 加法
*/
public Rational subtract (Rational subtrahend)throws Exception {
long n=numerator *subtrahend .denominator-denominator *subtrahend  .numerator;
long d=denominator *subtrahend .denominator ;
return new Rational(n,d);
}
/**
* 减法
*/
public Rational multply (Rational multiplicand)throws Exception {
long n=numerator *multiplicand .numerator;
long d=denominator *multiplicand .denominator ;
return new Rational(n,d);
}
/**
* 乘法
*/
public Rational divide(Rational divisor)throws Exception {
long n=numerator *divisor .denominator ;
long d=denominator *divisor .numerator;
return new Rational(n,d);
}
/**
* 除法
* @throws Exception
*/
public Rational abs() throws Exception{
return (this.numerator < 0 ? negate() : this);
}
private Rational negate() throws Exception {
long n=((this.numerator>0)?-1:1)*this.numerator;
return new Rational(n,this.denominator);
}
/**
* 获得绝对值
*/
public int signum() {
if(numerator >0) {
return 1;
}
else if(numerator<0) {
return -1;
}
else {
return 0;
}
}
/**此方法返回-1，0，或1，此Rational的值分类为负，零或正值。
*
*/
@Override
public int compareTo(Rational val) {
try {
if(this.subtract(val).numerator>0) {
return 1;
}
else if(this.subtract(val).numerator<0) {
return -1;
}
else {
return 0;
}
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return 0;

}
/**
* 比较大小
*/
public boolean equals(Object x) {
try {
if(this.subtract((Rational)x).numerator==0) {
return true;
}
else {
return false;
}
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return false;
}
@Override
public int intValue() {
// TODO 自动生成的方法存根
return (int)doubleValue();
}
/**
* 将Rational转为int
*/
@Override
public long longValue() {
// TODO 自动生成的方法存根
return (long)doubleValue();
}
/**
* 将Rational转为long
*/
@Override
public float floatValue() {
// TODO 自动生成的方法存根
return (float)doubleValue();
}
/**
* 将Rational转为float
*/

@Override
public double doubleValue() {
// TODO 自动生成的方法存根
return numerator *1.0/denominator ;
}
@Override
public String toString() {
if(denominator ==1) {
return numerator+"";
}
else {
return numerator +"/"+denominator ;
}
}
/**
* 覆盖Object类的toString方法
*/

}


1. Main.java(测试函数)

package test;

import rational.Rational;

public class Main {
public static void main(String[] args) throws Exception {
Rational test1=new Rational(2,6);
Rational test2=new Rational(-3,12);
//Rational test3=new Rational(2,0);
//可以作为非法报错
System.out.println("test1 - test2 = "+test1.subtract(test2));
System.out.println("test1 * test2 = "+test1.multply(test2));
System.out.println("test1 / test2 = "+test1.divide(test2));
System.out.println("abs(test2) = "+test2.abs());
switch(test2.signum()) {
case 0:
System.out.println("test2为0");
break;
case 1:
System.out.println("test2为正数");
break;
case -1:
System.out.println("test2为负数");
break;

}
System.out.println("test2的int值为"+test2.intValue());
System.out.println("test2的long值为"+test2.longValue());
System.out.println("test2的float值为"+test2.floatValue());
System.out.println("test2的double值为"+test2.doubleValue());
System.out.println("test2的String值为"+test2.toString());
}

}


1. 运行截图

1. 正常运行

2. 除0时模仿IDEA的报错格式

2. 下载代码附件

## 2. 讨论

1. 尝试描述怎么与c语言的有理数代码相比较,为什么你设计的类更加面向对象?

2. 因为设计的类的方法和属性是针对它本身特性来考虑的；如果是c语言的有理数代码，我会倾向于从过程考虑，考虑要写怎样的函数来用它，而不是考虑它应该会有怎样的方法

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

1. 别人如何复用你的代码?

1. 如果别人书写的是在不同包的其他类，可以通过导入我书写的类的包等方法，就可以使用我写的类和方法了，因为我的类是public修饰的，然后可以通过继承（如果他要建的新类和我的类是is-a关系）和组合来复用我的代码
2. 别人的代码是否依赖你的有理数类的属性?当你的有理数类的属性修改时,是否会影响他人调用你有理数类的代码?

1. 别人的代码是依赖于我的有理数类的属性，因为他在另一个类中使用了我的类，且两个类不在一个包内。但是我的有理数类的属性为private型，所以我的有理数类的属性修改时，不会影响他人调用我的有理数代码
3. 有理数类的public方法是否设置合适?为什么有的方法设置为private?

1. 我觉得我的public方法设置合适，因为我希望一些方法可以被使用。有些协助完成public方法且不希望被别人使用的方法我会设置为private,从而隐藏类的实现细节和保护类的数据；比如我的gcd代码，我不希望他人在别的类中使用，只限于在Rational类中辅助有参构造
posted @ 2020-10-02 08:18  rghli(林洁颖)  阅读(690)  评论(0编辑  收藏  举报