Как я могу делегировать члену в Scala?

Возможно ли в 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?

Ответы

Ответ 1

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

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

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

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

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
  ...
}

Ответ 2

Если вы можете сделать 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 = [email protected]

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

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

scala> res51.z
res54: java.lang.String = baz