• 20-4 案例分析:货币(抽象类型的应用)


      这个案例很好地解释了Scala中抽象类型的应用。我们的任务是设计一个Currency类。一个典型的Currency实例可以用来代表以美元、欧元、日元或其他货币表示的金额。它应该支持对货币金额的计算。例如,应该能将相同货币额度的两笔金额相加,或者可以用表示利率的因子对某笔货币金额做乘法。同时添加两个改良点,一、支持子单位;二、支持货币转换的功能。

    ①抽象类CurrencyZone

    abstract class CurrencyZone {
      //抽象类型
      type Currency <: AbstractCurrency
    
      //抽象值val
      val CurrencyUnit: Currency
    
      //抽象方法
      def make(x: Long): Currency
    
      abstract class AbstractCurrency{
    
        val amount: Long
    
        def designation: String
    
        def +(that: Currency): Currency = make(this.amount + that.amount)
    
        def *(x: Double): Currency = make((this.amount * x).toLong)
    
        def -(that: Currency): Currency = make(this.amount - that.amount)
    
        def /(that: Double) = make((this.amount / that).toLong)
    
        def  /(that: Currency) = this.amount.toDouble / that.amount
    
        //将给定的源货币转换成当前的Currency对象
        def from(other: CurrencyZone#AbstractCurrency): Currency = {
          make(math.round(other.amount.toDouble *  Converter.exchangeRate(other.designation)(this.designation)))
        }
    
        //入参n为1单位货币包含的amount,如1美元的amount为100,val Dollar = make(100)。
        private def decimals(n: Long): Int = if (n == 1) 0 else 1 + decimals(n / 10)
    
        //amount需除以1单位包含的amount显示
        override def toString: String =
          ((amount.toDouble / CurrencyUnit.amount.toDouble) formatted("%." + decimals(CurrencyUnit.amount) + "f")
            + " " + designation)
      }
      
    }
    

    ②汇率转换对象

    object Converter {
    
      var exchangeRate = Map(
        "USD" -> Map("USD" -> 1.0, "EUR" -> 0.7596, "JPY" -> 1.211, "CHF" -> 1.223),
        "EUR" -> Map("USD" -> 1.316,"EUR" -> 1.0, "JPY" -> 1.594, "CHF" -> 1.632),
        "JPY" -> Map("USD" -> 0.8257,"EUR" -> 0.6272, "JPY" -> 1.0, "CHF" -> 1.018),
        "CHF" -> Map("USD" -> 0.8108,"EUR" -> 0.6160, "JPY" -> 0.982, "CHF" -> 1.0),
      )
    
    }
    

     

    ③美元对象

    object US extends CurrencyZone {
    
      abstract class Dollar extends AbstractCurrency{
        override def designation: String = "USD"
      }
    
      override type Currency = Dollar
    
      override def make(cents: Long): Dollar = new Dollar {
        override val amount: Long = cents
      }
    
      val Cent = make(1)
      val Dollar = make(100)
      val CurrencyUnit = Dollar
    }
    

    ④欧元对象

    object Europe extends CurrencyZone {
      abstract class Euro extends AbstractCurrency{
        override def designation: String = "EUR"
      }
    
      override type Currency = Euro
    
      override def make(cents: Long): Euro = new Euro {
        override val amount: Long = cents
      }
    
      val Cent = make(1)
      val Euro = make(100)
      val CurrencyUnit = Euro
    }
    

    ⑤日元对象

    object Japan extends CurrencyZone{
      abstract class Yen extends AbstractCurrency{
        override def designation: String = "JPY"
      }
    
      override type Currency = Yen
    
      override def make(yen: Long): Yen = new Yen {
        override val amount: Long = yen
      }
    
      val Yen = make(1)
      val CurrencyUnit = Yen
    }
    

    ⑥测试类

    object Test {
      def main(args: Array[String]): Unit = {
        val res1 = Japan.Yen from US.Dollar * 100
        println(res1)
    
        val res2 = Europe.Euro from res1
        println(res2)
    
        val res3 = US.Dollar from res2
        println(res3)
    
        val res4 = US.Dollar * 100 + res3
        println(res4)
      }
    }
    

     控制台输出

    12110 JPY
    75.95 EUR
    99.95 USD
    199.95 USD
  • 相关阅读:
    Android 五大布局
    jdk6的安装以及环境变量的设置
    PLSQL Developer图形化窗口创建数据库全过程
    未能加载文件或程序集“Oracle.DataAccess, " 64位OS运行32位程序的问题
    Android SDK 无法连接到GOOGLE 下载安装包
    Android开发之旅:环境搭建
    Android开发把项目打包成apk
    在 VMware Workstation 虚拟机中创建共享文件夹的步骤〔图解〕
    谈谈对于企业级系统架构的理解
    C#图片处理之: 获取数码相片的EXIF信息
  • 原文地址:https://www.cnblogs.com/noyouth/p/14300254.html
Copyright © 2020-2023  润新知