Can anyone explain the subtype(<:) in the following code? Why it could be used like that? When we use that? Thanks.
trait SwingApi {
type ValueChanged <: Event
val ValueChanged: {
def unapply(x: Event): Option[TextField]
}
type ButtonClicked <: Event
val ButtonClicked: {
def unapply(x: Event): Option[Button]
}
type TextField <: {
def text: String
def subscribe(r: Reaction): Unit
def unsubscribe(r: Reaction): Unit
}
type Button <: {
def subscribe(r: Reaction): Unit
def unsubscribe(r: Reaction): Unit
}
}
I know that code! :)
So let's make sure you understand what
<:
means, just in case.A <: B
means thatA
must be a subtype ofB
, or, to put it in other words, every instance ofA
will be an instance ofB
as well (but not vice versa).We know, for example, that every java class is
<: Object
(such asString <: Object
).Next, why
type ValueChanged <: Event
. This is usually found in the cake pattern, but I'll skip an explanation of that (the lesson did mention the cake pattern, and provided a link iirc).What that means is that for anything that extends
SwingApi
, the typeValueChanged
must be a subtype ofEvent
. That makes it possible to callEvent
methods on anything that is declared with the typeValueChanged
, without knowing beforehand exactly what type is that.That is similar to the next use:
We are declaring here that
TextField
should have those methods, so when we get something of the typeTextField
(such as returned by theValueChanged
extractor), we can call these methods on it. We could write code like this:At this point, neither
SwingApi
norMyStuff
know what types are going to be used forValueChanged
orTextField
, and, yet, they can use them in normal code.One interesting fact that is often overlooked about
type
declarations is that they can be overridden by classes. That is, I can write something like this:Finally, you might wonder what use is this. I'll give one example. Naturally, you want the production code to show graphical elements on the screen and such, and, perhaps, you could write a separate class that implements it in a web server. But, and I think course takes advantage of it, you could write the class that implements it not as something that displays these components, but as test classes, that verify that the interaction with these components is being done correctly.
That is, you can have a
SwingImpl
that extendsSwingApi
and show the stuff on your desktop, and aSwingTest
that also extendsSwingApi
, but simply let people verify what is being done.