2

I want to design a class that serves as a wrapper around any other class. Let's call this wrapper class Virtual and it is used as follows:

val x: String = "foo"
val y: Virtual[String] = new Virtual(x)
// any method that can be called on x can also be called on y,
// i.e., Virtual[String] <: String

// example:
y.toUpperCase // will change the wrapped string to an upper case

This is what I have so far:

class Virtual[T](obj: T) extends T {
  // any Virtual specific methods here
}

Extending the type parameter does not seem to do the trick...

In other words: How can I ensure that the methods exposed by the class wrapped by Virtual are also exposed by the Virtual class itself?

Maarten
  • 207
  • 2
  • 13
  • 4
    I don't think you can have `Virtual[T]` automatically implement the methods of `T`, but if what you are after is something that gives you everything a `T` is but lets you add some more methods, you can use Scala's implicit classes for that. Then `x` would effectively have all of `String`'s methods, plus whatever else you might want. See e.g [WrappedString](https://www.scala-lang.org/api/current/scala/collection/immutable/WrappedString.html) (given effect with implicit conversion methods in `Predef.scala` rather than by an implicit class, but it's the same idea) – Steve Waldman Apr 09 '19 at 20:39

1 Answers1

2

As suggested in comments and in Kevin's answer, try using implicit conversion like so

object Hello extends App {
  class Virtual[T](val delegate: T) {
    def bar(i: Int): Int = i + 1
  }
  implicit def VirtualToDelegate[T](virtual: Virtual[T]): T = virtual.delegate
  val str = "foo"
  val virtual = new Virtual[String](str)
  println(virtual.toUpperCase) // FOO
  println(virtual.bar(7))      // 8
}

Mario Galic
  • 47,285
  • 6
  • 56
  • 98