Java有理数类的设计

本文介绍了如何使用Java设计一个面向对象的有理数类,包括构造方法、最大公因数计算、约分等功能。通过与C语言的有理数代码对比,阐述了Java面向对象的优势,如代码复用、封装和数据安全性。并提供了测试代码以展示类的使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

仿照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修饰符修饰,保证类不能被继承。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值