Как я могу делегировать члену в Scala? - PullRequest
16 голосов
/ 29 марта 2011

Возможно ли в Scala написать что-то вроде:

trait Road {
  ...
}

class BridgeCauseway extends Road {
  // implements method in Road
}

class Bridge extends Road {
  val roadway = new BridgeCauseway()

  // delegate all Bridge methods to the `roadway` member
}

или мне нужно реализовать каждый из Road методов, один за другим, и вызвать соответствующий метод на roadway?

Ответы [ 2 ]

18 голосов
/ 29 марта 2011

Самый простой способ сделать это - неявное преобразование вместо расширения класса:

class Bridge { ... }
implicit def bridge2road(b: Bridge) = b.roadway

до тех пор, пока вы не нуждаетесь в оригинальном Bridge, который нужно взять с собой в поездку (например, вы собираетесь хранить Bridge в коллекции Road).

Если вам нужно вернуть Bridge снова, вы можете добавить owner метод в Road, который возвращает Any, установить его с помощью параметра конструктора для BridgeCauseway, а затем pattern- матч, чтобы получить свой мост:

trait Road {
  def owner: Any
  ...
}

class BridgeCauseway(val owner: Bridge) extends Road { . . . }

class Bridge extends Road {
  val roadway = new BridgeCauseway(this)
  ...
}

myBridgeCauseway.owner match {
  case b: Bridge => // Do bridge-specific stuff
  ...
}
3 голосов
/ 30 марта 2011

Если вы можете сделать Bridge a trait, вы будете отсортированы.

scala> trait A {
     |   val x: String
     | }
defined trait A

scala> class B extends A {
     |   val x = "foo"
     |   val y = "bar"
     | }
defined class B

scala> trait C extends A { self: B =>         
     |   val z = "baz"               
     | }
defined trait C

scala> new B with C
res51: B with C = $anon$1@1b4e829

scala> res51.x
res52: java.lang.String = foo

scala> res51.y
res53: java.lang.String = bar

scala> res51.z
res54: java.lang.String = baz
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...