方法覆盖,继承和对象

时间:2018-11-24 22:19:16

标签: scala inheritance override abstract-class

请记住,我一周前开始使用Scala。

课程: 货币-抽象,比特币,美元,欧元

特质: 转换器,打印机

我的抽象类有2个变量: Name Value (均为变量)

转换器特性中的方法

def convert(to:Currency):Double = ???

这是我卡住的部分。我需要在每个子类(货币)中重写此方法,以便它们从一种货币转换为另一种货币。我可以用新方法来做,但是需要用一种方法来做。我应该将什么作为参数传递,以便该方法识别将其转换为哪个参数。 欧元,美元和比特币仅采用一个整数作为参数。

我也不理解参数的“ to:”部分。

由于这也是我关于Stack Overflow的第一个问题,我不太确定这是如何工作的,我想指出,我很期待指针和/或建议,因为简单的解决方案不会从长远来看对我有帮助。如果你们中的某些人认为我遗漏了一些重要信息,请随时告诉我,我会很乐意编辑我的问题。

2 个答案:

答案 0 :(得分:1)

to: Currency表示您正在声明一个名为to的参数,其类型为Currency。不幸的是,您不希望使用Currency对象,因为其中包含特定金额-您只想将应该返回的货币类传递给它。

好吧,你可以这样:

def convert(to: Class[Currency]): Double = ???

但是类型安全性更高的方法是这样做:

def convert[C <: Currency](to: Class[C]): C = ???

但是我不确定您将如何实现这一目标。您可能需要为此使用Manifest而不是Class

答案 1 :(得分:0)

欢迎使用 StackOverflow

首先,作为对以后问题的建议,请尝试提供所有可以的(相关)代码-例如,在这种情况下,并发类的定义将很有用。

第二,我相信这是一项任务,可能您不需要走得太远。
正如Robin所说的那样,此to参数用于确定目标类型-但由于它将是一个类,因此它将具有一个值,这是不希望的。
我想这个想法是传递一个空类,然后使用 pattern matching 进行类似的操作。

class Bitcoin(override val amount: Int = 0) extends Concurrency(amount) {
  override def convert(to: Concurrency): Concurrency = to match {
    case _: Bitcoin => this // no need to transform
    case _: Euro    => new Euro((this.amount / 2).toInt)
    case _: Dollar  => new Dollar((this.amount / 3).toInt)
  }
}

new Bitcoin(30).convert(to = new Dollar()) // res0: Concurrency: Dollar(10)

第三,这是一个类型安全性更高的解决方案,希望您能找到有趣且“有趣” (部分)-故意开玩笑。

sealed abstract class Concurrency(val amount: Int) {
  def name: String

  /** Tansforms this concurrency value to a new target type. */
  final def to[C <: Concurrency](implicit builder: Concurrency.Builder[C]): C =
    builder.build(this)
}

object Concurrency {
  /** Builder of target concurrencies. */
  trait Builder[C <: Concurrency] {
    def build(origin: Concurrency): C
  }
}

final case class Bitcoin(override val amount: Int) extends Concurrency(amount) {
  override final val name: String = "Bitcoin"
}

object Bitcoin {
  import Concurrency.Builder

  implicit val BitcoinBuilder: Builder[Bitcoin] = new Builder[Bitcoin] {
    override def build(origin: Concurrency): Bitcoin = origin match {
      case b: Bitcoin     => b // no need to transform
      case Euro(amount)   => Bitcoin(amount * 2)
      case Dollar(amount) => Bitcoin(amount * 3)
    }
  }
}

final case class Euro(override val amount: Int) extends Concurrency(amount) {
  override final val name: String = "Euro"
}

object Euro {
  import Concurrency.Builder

  implicit val EuroBuilder: Builder[Euro] = new Builder[Euro] {
    override def build(origin: Concurrency): Euro = origin match {
      case e: Euro         => e // no need to transform
      case Bitcoin(amount) => Euro((amount / 2).toInt)
      case Dollar(amount)  => Euro((amount / 1.5).toInt)
    }
  }
}

final case class Dollar(override val amount: Int) extends Concurrency(amount) {
  override final val name: String = "Dollar"
}

object Dollar {
  import Concurrency.Builder

  implicit val DollarBuilder: Builder[Dollar] = new Builder[Dollar] {
    override def build(origin: Concurrency): Dollar = origin match {
      case d: Dollar       => d // no need to transform
      case Euro(amount)    => Dollar((amount * 1.5).toInt)
      case Bitcoin(amount) => Dollar((amount / 3).toInt)
    }
  }
}

Dollar(10).to[Bitcoin] // res0: Bitcoin = Bitcoin(30)

毫无疑问地要求澄清。