I am stuck with a "simple" problem. I am working with files metadata. I would like to provide both a read-only view (trait ReadOnly
) with just getters as well as a read-write view (trait ReadWrite
) with getters and setters. Each read-write view must extend a read-only view.
trait ReadOnly
trait ReadWrite
trait BasicRO extends ReadOnly {
def foo: String
def bar: Int
}
class BasicRW extends ReadWrite with BasicRO {
def foo: String = ???
def foo_=( str: String ): Unit = ???
def bar: Int = ???
def bar_=( i: Int ): Unit = ???
}
So far so good. But now, I would like to add a snapshot
method to ReadWrite
which will return the corresponding ReadOnly
view (the same that was extended by the ReadWrite
sub-class). In pseudo-scala, I would like to define this constraint as:
trait ReadWrite[T <: ReadOnly] extends T {
def snaphsot: T
}
But it does not compile because class type required but T found
(compiler message). Is there a way to express this constraint in the Scala type-system ?
Just to be clear, you want snapshot to be in a separate trait, but it can only be used in a class which also extends ReadOnly?
You can use a self type for this
trait ReadOnly[T]
trait ReadWrite[T] { self: ReadOnly[T] =>
def snapshot: T
}
trait BasicRO[T] extends ReadOnly[T] {
def foo: String
def bar: Int
}
abstract class class1[T] extends ReadOnly[T] with ReadWrite[T] // legal
abstract class class2[T] extends ReadWrite[T] // Not legal
abstract class class3[T] extends BasicRO[T] with ReadWrite[T] // legal
This doesn't make ReadWrite
extend ReadOnly
, but it both requires that the base object also mix in a ReadOnly
(with the same type parameter) and gives ReadWrite
access to ReadOnly
's methods, while allowing the two traits to be subclassed entirely independently of eachother.