Java程序设计作业01 - 有理数类的设计
1.给出你的有理数类代码
package rationalnumber;
public class Rational {
private int numerator; //分子
private int denominator; //分母
public int getNumerator() { //获取分子
return numerator;
}
public int getDenominator() { //获取分母
return denominator;
}
public Rational() { //默认构造
this.numerator = 0;
this.denominator = 1;
}
public Rational(int x) { //只有整数时构造有理数
if(x < 0) {
this.numerator = -x;
this.denominator = -1;
}else {
this.numerator = x;
this.denominator = 1;
}
}
public Rational(int numerator, int denominator) { //以分子、分母形式构造有理数
if(denominator == 0) {
System.out.println("分母不能为零!");
System.exit(1);
}else if(numerator == 0){
this.numerator = 0;
this.denominator = 1;
return;
}
int gcd = getGCD(numerator, denominator);
this.numerator = numerator / gcd;
this.denominator = denominator / gcd;
}
public Rational(Double x) { //直接输入小数时构造有理数
int flag = 0;
if(x < 0) {
flag = 1;
x = -x;
}
String s = x.toString();
String[] str = new String[2];
str = s.split("\.");
int num = (int) (Integer.parseInt(str[0]) * Math.pow(10, str[1].length()) + Integer.parseInt(str[1]));
int den = (int) Math.pow(10, str[1].length());
if(flag == 1)
den = -den;
int gcd = getGCD(num, den);
this.numerator = num / gcd;
this.denominator = den / gcd;
}
private int getGCD(int a, int b) { //获取最大公约数,用于化简分式
int t = 0;
if(a < b) {
t = a;
a = b;
b = t;
}
t = a % b;
while(t != 0) {
a = b;
b = t;
t = a % b;
}
return b;
}
public Rational add(Rational a) { //相加
int num = a.numerator * this.denominator + a.denominator * this.numerator;
int den = a.denominator * this.denominator;
Rational r = new Rational(num, den);
return r;
}
public Rational minus(Rational a) { //相减
int num = this.numerator * a.denominator - this.denominator * a.numerator;
int den = a.denominator * this.denominator;
Rational r = new Rational(num, den);
return r;
}
public Rational mulitply(Rational a) { //相乘
int num = a.numerator * this.numerator;
int den = a.denominator * this.denominator;
Rational r = new Rational(num, den);
return r;
}
public Rational divide(Rational a) { //相除
int num = a.numerator * this.denominator;
int den = a.denominator * this.numerator;
Rational r = new Rational(num, den);
return r;
}
public Rational abs() { //取绝对值
int num = (this.numerator < 0 ? this.numerator : -this.numerator);
int den = (this.denominator < 0 ? this.denominator : -this.denominator);
Rational r = new Rational(num, den);
return r;
}
public Rational pow(Rational a, int n) { //取有理数a的n次方
int num = a.numerator;
int den = a.denominator;
for(int i = 1; i < n; i++) {
num = num * a.numerator;
den = den * a.denominator;
}
Rational r = new Rational(num, den);
return r;
}
public Rational remainder(Rational a) { //取余
if(this.divide(a).denominator == 1)
return new Rational(0, 1);
Rational r = new Rational();
int x = this.divide(a).numerator / this.divide(a).denominator + 1;
r = this.minus((new Rational(x, 1)).mulitply(a));
return r;
}
public int compareTo(Rational a) { //比较两个有理数的大小,
int x = this.numerator * a.denominator;
int y = a.numerator * this.denominator;
if(x > y) { //-1、0、1分别代表左边小于、等于、大于右边
return 1;
}else if(x < y) {
return -1;
}else {
return 0;
}
}
public int signum() { //返回有理数的正负符号
if(this.denominator < 0)
return -1;
return 1;
}
public int intValue() { //转化为int类型
return (int) this.numerator / this.denominator;
}
public float floatValue(){ //转化为float类型(其余类型代码类似,故不重复)
return (float) this.numerator / this.denominator;
}
public String toString() { //将有理数转化成分数的字符串形式
if(this.numerator == 0) {
return "0";
}else if(this.denominator == 1){
return this.numerator + "";
}else {
String s = "(" + ((double) this.numerator / this.denominator) + ")";
return this.numerator + "/" + this.denominator + s;
}
}
}
2.给出你的测试代码
import java.util.Scanner;
import rationalnumber.Rational;
public class Main {
public static void main(String[] args) {
//Scanner sc = new Scanner(System.in);
Rational r1 = new Rational(1, 2);
Rational r2 = new Rational(0.4);
Rational r = new Rational();
System.out.println("r1 = " + r1.toString() + " ; " + "r2 = " + r2.toString());
System.out.println("r1 + r2 = " + r1.add(r2).toString());
System.out.println("r1 - r2 = " + r1.minus(r2).toString());
System.out.println("r1 * r2 = " + r1.mulitply(r2).toString());
System.out.println("r1 / r2 = " + r1.divide(r2).toString());
System.out.println("abs(r1) = " + r1.abs().toString());
System.out.println("(r1)^2 = " + r.pow(r1, 2).toString());
System.out.println("r1 % r2 = " + r1.remainder(r2).toString());
System.out.println("r1 compare to r1 = " + r1.compareTo(r2));
System.out.println("r1's signum = " + r1.signum());
System.out.println("r1 to Integer = " + r1.intValue());
}
}
测试结果图:
(1)r1 = Rational(1,2); r2 = Rational(0.4)
(2)r1 = Rational(-1,1); r2 = Rational(-1.6)
3.类名、变量名命名需符合Java规范
- 包名全部小写、类名首字母大写、变量名命名使用驼峰法。
4.尝试描述怎么与c语言的有理数代码相比较,为什么你设计的类更加面向对象?
- C语言的代码在编写过程中更偏向于过程,所以在设计过程中会更偏向于函数的设计。在Java类的设计中我们会更注重于类的方法和属性的编写,该如何让这些东西联系在一起、如何封装则是考虑的重点,并且与C语言相比,Java重载函数的特性让它更突出面向对象的特点,例如在该作业中通过不同的方式初始化构造有理数。
5.尝试从代码复用的角度来描述你设计的有理数类。从几个方面讨论。
-
别人如何复用你的代码?
可以导入我所写的rationalnumber包中的有理数类,就可以使用该类中的内容了。 -
别人的代码是否依赖你的有理数类的属性?当你的有理数类的属性修改时,是否会影响他人调用你有理数类的代码?
别人的代码依赖我的有理数类的属性。当我的有理数类的属性修改时,比如将int改成double类型时会影响到他人调用代码。(其实我没看懂这题的意思) -
有理数类的public方法是否设置合适?为什么有的方法设置为private?
合适,因为其中的大部分方法我希望他们能在包外也能够调用,有的方法设置成private可以将方法限制于该类中访问,例如在本作业中的用于化简分数的获取最大公约数函数getGCD,我只想它用于新的有理数化简,而不希望其他调用,因此设计成了private方法。