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 <: Bmeans thatAmust be a subtype ofB, or, to put it in other words, every instance ofAwill be an instance ofBas 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 typeValueChangedmust be a subtype ofEvent. That makes it possible to callEventmethods 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
TextFieldshould have those methods, so when we get something of the typeTextField(such as returned by theValueChangedextractor), we can call these methods on it. We could write code like this:At this point, neither
SwingApinorMyStuffknow what types are going to be used forValueChangedorTextField, and, yet, they can use them in normal code.One interesting fact that is often overlooked about
typedeclarations 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
SwingImplthat extendsSwingApiand show the stuff on your desktop, and aSwingTestthat also extendsSwingApi, but simply let people verify what is being done.