Переопределение метода, наследование и объекты - PullRequest
0 голосов
/ 25 ноября 2018

Помните, что я начал со Scala неделю назад.

Классы : валюта - аннотация, биткойн, доллар, евро

Черты: Конвертер, принтер

В моем абстрактном классе есть2 переменные: Имя и Значение (обе переменные)

Метод в свойствах конвертера

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

Это та часть, где я застрял.Мне нужно переопределить этот метод в каждом из моих подклассов (Валюты), чтобы они конвертировали из одной Валюты в две другие.Я могу сделать это с помощью новых методов, но это нужно сделать одним.Что я должен передать в качестве параметра, чтобы метод распознал, в какой из них его преобразовать.Евро, доллар и биткойны принимают только один Int в качестве параметра.

Что я также не понимаю, так это часть параметра «to:».

Поскольку это также мой первый вопрос оПереполнение стека, и я не совсем уверен, как все это работает, я хотел бы отметить, что я с нетерпением жду указателей и / или предложений, поскольку простое решение не поможет мне в долгосрочной перспективе.Если некоторые из вас сочтут, что я пропустил какую-то важную информацию, не стесняйтесь сообщить мне, я с удовольствием отредактирую свой вопрос.

Ответы [ 2 ]

0 голосов
/ 25 ноября 2018

Добро пожаловать на StackOverflow .

Во-первых, в качестве совета для будущих вопросов постарайтесь предоставить весь код (соответствующий) , который вы можете - например, вв этом случае было бы полезно определить ваши классы параллелизма.

Во-вторых, я считаю, что это задание, и, вероятно, вам не нужно заходить слишком далеко.
Как уже сказал Робин, это toПараметр используется для определения целевого типа, но, поскольку это будет класс, он будет иметь значение, которое нежелательно.
Я полагаю, идея состоит в том, чтобы передать пустой класс и сделать что-то подобное, используя сопоставление с образцом .

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)

Не сомневайтесь, попросите разъяснений.

0 голосов
/ 25 ноября 2018

to: Currency означает, что вы объявляете параметр с именем to, тип которого Currency.К сожалению, вам не нужен объект Currency, потому что он содержит определенную сумму - вам просто нужно передать класс валюты, которая должна быть возвращена.

Что ж, вы можете сделать это следующим образом:

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

Но более безопасным для типов способом было бы сделать это так:

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

но я не уверен, как бы вы реализовали это.Возможно, вам придется использовать Manifest вместо Class для этого.

...