当前位置: 首页 > news >正文

面向对象—有理数类的设计

目录

1.代码呈现

1.1编写toString、equals方法

1.2测试代码

1.3有理数类的代码

2.论述题

3.有理类设计

1.代码呈现

1.1编写toString、equals方法

(1)toString方法

@Overridepublic String toString(){if(this.v2==0){return "Undefined";}return this.v1 +"/"+ this.v2;}

(2)equals方法

 @Overridepublic boolean equals(Object obj) {// 首先检查引用是否相同if (this == obj) {return true;}// 检查是否为同一个类的对象if (!(obj instanceof Rational)) {return false;}// 强制转换为 Rational 类型Rational other = (Rational) obj;// 检查分母是否为零,如果其中一个对象的分母为零,则它们不能相等if( v2 == 0 || other.v2 == 0) {return false;}// 计算两个有理数的交叉乘积并比较return (v1 * other.v2) == (other.v1 * v2);}

1.2测试代码

(1)在与有理数类不同包的其他类中调用有理数类

(2)测试代码与测试结果

package test01;import Rational.Rational;public class Rationaltest {public static void main(String[] args) {// 创建两个有理数对象Rational r1 = new Rational(1, 2); // 1/2Rational r2 = new Rational(3, 4); // 3/4// 创建第三个对象用于存放结果Rational result = new Rational(0, 1);//分母不能为0// 测试加法System.out.println("Adding 1/2 and 3/4:");r1.Add(r1, r2, result);System.out.println("Result= " + result.getV1() + "/" + result.getV2());// 测试乘法System.out.println("Multiplying 1/2 and 3/4:");r1.Multiply(r1, r2, result);System.out.println("Result= " + result.getV1() + "/" + result.getV2());//测试getRationalSystem.out.println("getRational:");int e=0;System.out.println("e="+r1.getRational(r1,2,e));//toStringSystem.out.println("r1 的输出结果为: ");System.out.println("r1 = "+r1.toString());//equalsSystem.out.println("r1和r2的比较结果为:");System.out.println(r1.equals(r2));}
}

1.3有理数类的代码

package Rational;public class Rational{//属性private int v1;private int v2;//构造函数public Rational(int v1,int v2){this.v1=v1;this.v2=v2;}//setter与getterpublic int getV1() {return v1;}public void setV1(int v1) {this.v1 = v1;}public int getV2() {return v2;}public void setV2(int v2) {this.v2 = v2;}//方法//add方法public void Add(Rational T1,Rational T2,Rational T3){int t;T3.v2 = T1.v2 * T2.v2;T3.v1 = T1.v1 * T2.v2 + T2.v1 * T1.v2;t = Gcd(T3.v2,T3.v1);T3.v2 /= t;T3.v1 /= t;}//Multiply方法public void Multiply(Rational T1,Rational T2,Rational T3){int t;T3.v2 = T1.v2 * T2.v2;T3.v1 = T1.v1 * T2.v1;t = Gcd(T3.v2, T3.v1);T3.v2 /= t;T3.v1 /= t;}private static int Gcd(int m,int n){int t;while(m % n != 0){t = n;n = m%n;m = t;}return n;}public int getRational(Rational T,int i,int e){if(i==1){e=T.v1;}else{e=T.v2;}return e;}@Overridepublic String toString(){if(this.v2==0){return "Undefined";}return this.v1 +"/"+ this.v2;}@Overridepublic boolean equals(Object obj) {// 首先检查引用是否相同if (this == obj) {return true;}// 检查是否为同一个类的对象if (!(obj instanceof Rational)) {return false;}// 强制转换为 Rational 类型Rational other = (Rational) obj;// 检查分母是否为零,如果其中一个对象的分母为零,则它们不能相等if( v2 == 0 || other.v2 == 0) {return false;}// 计算两个有理数的交叉乘积并比较return (v1 * other.v2) == (other.v1 * v2);}
}

2.论述题

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

(1)

  • 在Java中,我们利用类来封装数据和行为。我们将有理数的分子分母封装在一个类里,并通过方法(get方法)的调用来访问数据,且类里的数据都被保护起来,不允许外部直接修改。
  • 而在C语言中,通常利用结构体来存储数据,数据是公开的可以任意修改。

(2)

  • 在 Java 中,方法属于类的一部分。每个 Rational对象都有自己的方法,如加法、减法等。这些方法可以直接在对象上调用,使得代码更加直观和易于理解。
  • 在 C 语言中,方法通常是独立于数据结构的全局函数。虽然可以通过传递指向结构体的指针来操作数据,但这不如 Java 中的对象方法那样自然。

(3)

  • Java 支持继承,允许从现有类派生新类(利用extends关键字)。子类可以复用父类的行为并添加新的特性。
  • C 语言没有内置的继承机制。虽然可以通过包含结构体或其他技巧来模拟继承,但这种做法并不像 Java 中那么直接和强大。

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

2.1别人如何复用你的代码? 

(1)通过注释了解类的属性和方法,必要时在JDK文档中查找类的功能

(2)通过代码测试检测代码是否可以正常运行

2.2别人的代码是否依赖你的有理数类的内部属性?当你升级了你的有理数类,将其的属性名改变时。是否会影响他人以前编写的调用你有理数类的代码(假设他将使用了你升级后有理数类)?

(1)封装是面向对象编程的一个核心原则,它确保了对象的内部状态对外部是不可见的,并且只能通过定义好的方法来访问和修改。

(2)私有化(private)Rational类的属性且提供公共的方法(getV1()和getV2())访问。

(3)ational 类遵循了良好的封装原则,并且外部代码只通过公共接口(如 getter 和 setter 方法、运算方法等)来访问和操作 Rational 对象,那么更改类的内部属性名不会影响外部代码。这是因为外部代码并不直接依赖于这些内部属性。

2.3有理数类的public方法是否设置合适?为什么有的方法设置为private?

(1)Rational类中的public方法有:构造函数,setter与getter方法,运算方法(add,multiply),toString(),equals()。

公共方法是类对外提供的接口,用户可以通过这些方法与对象进行交互。

(2)Rational类中的private方法有:Gcd()。

私有方法是类的内部实现细节,外部代码无法直接调用这些方法。将类中的辅助方法(Gcd())设为私有方法。避免外部代码直接调用他们,有利于保护内部的状态。

2.4你的类里面有static属性或方法吗?如果有,为什么要设置为static的?

类中的工具方法(提供辅助的方法),如Rational类中的Gcd()。设置为static那么方法可以通过类名直接调用,而不需要创建类的实例。

//求最大公约数
private static int Gcd(int m,int n){int t;while(m % n != 0){t = n;n = m%n;m = t;}return n;}

3.有理类设计

在设计面向对象的有理数类时,我深刻体会到了面向对象编程的精髓,也发现了自己在设计过程中的一些不足。

有理数类的设计需要考虑数据的封装、方法的实现以及异常处理等多个方面。通过将分子和分母封装为私有成员变量,并提供公共的构造函数和方法,我成功实现了有理数的基本运算,如加法、减法、乘法和除法。同时,我也为有理数类添加了化简功能,确保结果总是以最简形式表示。

然而,在设计过程中,我也遇到了一些问题。例如,我没有充分考虑到分母为零的情况,导致程序在运行时可能会出现异常。此外,在实现有理数的比较方法时,我最初没有考虑到浮点数精度问题,导致比较结果可能不准确。通过不断调试和优化,我逐步解决了这些问题,并加深了对面向对象编程的理解。

这次设计让我认识到,面向对象编程不仅仅是代码的封装,更是一种思维方式。我们需要从对象的角度去思考问题,将问题分解为一个个类和对象,并通过合理的方法和属性来实现功能。同时,我也意识到在设计过程中要充分考虑各种边界情况和异常情况,以提高程序的健壮性和可靠性。

相关文章:

  • 【软考-系统架构设计师】设计模式三大类型解析
  • Linux :进程替换
  • 模型加载常见问题
  • vue3 element-plus中的国际化在onMounted中的写法
  • 【Java学习笔记】位运算
  • vos3000外呼系统怎么给普通用户开通播放下载录音权限?
  • CSS 字体背景波浪
  • Linux操作系统--静态库和动态库的生成and四种解决加载找不到动态库的四种方法
  • 【2025最新版】火鸟门户v8.5系统源码+PC、H5、小程序 +数据化大屏插件
  • 健康养生指南
  • CMake Error at build/_deps/glog-src/CMakeLists.txt:1 (cmake_minimum_required):
  • MCP和A2A是什么?
  • Android利用MediaCodec和GLSurfaceView录制视频
  • HttpSessionAttributeListener 的用法笔记250417
  • Spring Boot 动态热更新 HTTPS 证书的实现与原理
  • 对夹式V型球阀:原理、优势与工业应用全解析
  • 【nginx】nginx的目录结构分析
  • 从零开始学A2A四:A2A 协议的安全性与多模态支持
  • CS144 Lab1实战记录:实现TCP重组器
  • git分支操作
  • 临沂市建设局网站/营销公司网站
  • 万网注册域名做简单网站/郑州网站seo外包公司
  • 网络彩票的网站怎么做/如何制作网页
  • wordpress评论表单/seo 优化思路
  • 怎么建立滚动网站/宁波网站seo诊断工具
  • 企业购 网站建设/网页在线生成