零度非安全 发表于 2017-3-12 14:11:36

【Java 教程(原创)】025.参数传值——有理数的类封装

本帖最后由 零度非安全 于 2017-4-7 11:09 编辑

点击图片穿越到 索引帖,听说有惊喜!



通过前面几节的学习,我们已经知道,面向对象编程的核心思想之一就是将数据和对数据的操作封装在一起。即通过抽象

从具体的实例中抽取共同的性质形成类的概念,再由类创建具体的对象,然后对象调用方法产生行为,以达到程序所要实现

的目的。

这讲对熟悉的有理数进行封装,以便巩固前面所学的知识。

1. Rational(有理数)类

分数也称为有理数,是我们熟悉的一种数。有时希望程序能对分数进行四则运算,而且两个分数四则运算的结果仍是分数

(不希望看到 1/6 + 1/6 的结果是小数的近似值 0.333,而是 1/3)。

以下用类实现对有理数的封装。有理数有两个重要的成员,即分子和分母,另外还有重要的四则运算。Rational(有理数)

类应当具有以下属性(成员变量)和功能(方法)。

(1)Rational 类有两个 int 型的成员变量,例如,名字分别为 numerator(分子)和 denominator(分母)。

(2)提供 Rational add(Rational r) 方法,即有理数调用该方法和参数指定的有理数做加法运算,并返回一个 Rational
         对象。

(3)提供 Rational sub(Rational r) 方法,即有理数调用该方法和参数指定的有理数做减法运算,并返回一个 Rational 对
         象。

(4)提供 Rational muti(Rational r) 方法,即有理数调用该方法和参数指定的有理数做乘法运算,并返回一个 Rational
         对象。

(5)提供 Rational div(Rational r) 方法,即有理数调用该方法和参数指定的有理数做除法运算,并返回一个 Rational 对
         象。

根据以上分析,给出的 Rational 类代码如下:

Rational.java
public class Rational{
   
    int numerator;                                          //分子
    int denominator;                                        //分母
   
    Rational(){
    }
   
    Rational(int a,int b){
      if(a == 0){
            numerator = 0;
            denominator = 1;
      }
      else{
            setNumeratorAndDenominator(a,b);
      }
    }
   
    void setNumeratorAndDenominator(int a,int b){         //设置分子和分母
      int c = f(Math.abs(a),Math.abs(b));               //计算最大公约数
      numerator = a / c;
      denominator = b / c;
      if(numerator < 0 && denominator < 0){
            numerator = -numerator;
            denominator = -denominator;
      }
    }
   
    int getNumerator(){
      return numerator;
    }
   
    int getDenominator(){
      return denominator;
    }
   
    int f(int a,int b){                                     //求a和b的最大公约数
      if(a < b){
            int c = a;
            a = b;
            b = c;
      }
      int r = a % b;
      while(r != 0){
            a = b;
            b = r;
            r = a % b;
      }
      return b;
    }
   
    Rational add(Rational r){                               //加法运算
      int a = r.getNumerator();
      int b = r.getDenominator();
      int newNumerator = numerator * b + denominator * a;
      int newDenominator = denominator * b;
      Rational result = new Rational(newNumerator,newDenominator);
      return result;
    }
   
    Rational sub(Rational r){                               //减法运算
      int a = r.getNumerator();
      int b = r.getDenominator();
      int newNumerator = numerator * b - denominator * a;
      int newDenominator = denominator * b;
      Rational result = new Rational(newNumerator,newDenominator);
      return result;
    }
   
    Rational muti(Rational r){                              //乘法运算
      int a = r.getNumerator();
      int b = r.getDenominator();
      int newNumerator = numerator * a;
      int newDenominator = denominator * b;
      Rational result = new Rational(newNumerator,newDenominator);
      return result;
    }
   
    Rational div(Rational r){                               //除法运算
      int a = r.getNumerator();
      int b = r.getDenominator();
      int newNumerator = numerator * b;
      int newDenominator = denominator * a;
      Rational result = new Rational(newNumerator,newDenominator);
      return result;
    }
   
}
2. 用 Rational 对象做运算

既然已经有了 Rational 类,那么就可以让类创建若干个对象,并让它们交互进行必要的四则运算来完成程序要达到的目

的。下面的主类 MainClass 使用 Rational 对象计算两个分数的四则运算,并计算 计算 2/1 + 3/2 + 5/3 + 8/5 + 13/8 + ···

的前 10 项和。

MainClass.java
public class MainClass{
   
    public static void main(String[] args){
      Rational r1 = new Rational(1,5);
      Rational r2 = new Rational(3,2);
      Rational result = r1.add(r2);
      int a = result.getNumerator();
      int b = result.getDenominator();
      System.out.println("1/5 + 3/2 = " + a + "/" + b);
      result = r1.sub(r2);
      a = result.getNumerator();
      b = result.getDenominator();
      System.out.println("1/5 - 3/2 = " + a + "/" + b);
      result = r1.muti(r2);
      a = result.getNumerator();
      b = result.getDenominator();
      System.out.println("1/5 × 3/2 = " + a + "/" + b);
      result = r1.div(r2);
      a = result.getNumerator();
      b = result.getDenominator();
      System.out.println("1/5 ÷ 3/2 = " + a + "/" + b);
      int n = 10,k = 1;
      System.out.println("计算 2/1 + 3/2 + 5/3 + 8/5 + 13/8 + ··· 的前" + n + "项和");
      Rational sum = new Rational(0,1);
      Rational item = new Rational(2,1);
      while(k <= n){
            sum = sum.add(item);
            k++;
            int fenzi = item.getNumerator();
            int fenmu = item.getDenominator();
            item.setNumeratorAndDenominator(fenzi + fenmu,fenzi);
      }
      a = sum.getNumerator();
      b = sum.getDenominator();
      System.out.println("用分数表示:");
      System.out.println(a + "/" + b);
      double doubleResult = (a * 1.0) / b;
      System.out.println("用小数表示:");
      System.out.println(doubleResult);
    }
   
}
运行效果如下所示:



【特别注意】贴子中的栗子希望鱼油们能自觉的手动敲上去,不要单纯的复制粘贴保存,然后编译运行。



☞点我前往上一讲☜
☞点我前往下一讲☜



摆渡终极鉴黄师 发表于 2017-3-16 16:48:19

{:10_257:}非安全辛苦了

零度非安全 发表于 2017-3-16 17:01:18

摆渡终极鉴黄师 发表于 2017-3-16 16:48
非安全辛苦了

听到这句话,我心里挺高兴的!!!{:10_264:}

摆渡终极鉴黄师 发表于 2017-3-16 17:11:30

零度非安全 发表于 2017-3-16 17:01
听到这句话,我心里挺高兴的!!!

{:10_297:}

安卓逆向 发表于 2017-4-4 10:19:41

感觉Java更难写啊

超凡天赐 发表于 2017-8-5 21:03:16

后面几期好像没有出作业{:10_250:}

reed2425537764 发表于 2018-9-17 13:45:49

最后一个求前10项和,int不行啊不够大,要用long吧?
页: [1]
查看完整版本: 【Java 教程(原创)】025.参数传值——有理数的类封装