Mic*_*ael 29 scala contravariance
我正在考虑以下示例来说明为什么逆变是有用的.
让我们考虑一个GUI框架Widgets,Events和Event Listeners.
abstract class Event;
class KeyEvent extends Event
class MouseEvent extends Event
trait EventListener[-E] { def listen(e:E) }Run Code Online (Sandbox Code Playgroud)
我们Widgets定义以下方法:
def addKeyEventListener(listener:EventListener[KeyEvent])
def addMouseEventListener(listener:EventListener[MouseEvent])
Run Code Online (Sandbox Code Playgroud)
这些方法只接受"特定"事件监听器,这很好.但是我想定义"kitchen-sink"监听器,它们监听所有事件,并将这些监听器传递给上面的"添加监听器"方法.
例如,我想定义LogEventListener记录所有传入的事件
class LogEventListener extends EventListener[Event] {
def listen(e:Event) { log(event) }
}Run Code Online (Sandbox Code Playgroud)
由于特征EventListener是逆变的,Event我们可以传递LogEventListener给所有那些"添加监听器"方法而不会失去其类型安全性.
是否有意义 ?
对我也有意义.根据经验,参数化类型Type[A]在A 每次A通过接受它们作为参数来接受与它们做某事的实例时,应该相对于它的类型参数是逆变的.
例如,Java类型Comparator[T](如果已在Scala中定义)将具有逆变性:a Comparator[Any]应该是子类型Comparator[String],因为它可以比较可以比较的所有对象Comparator[String],等等.最一般的例子是类的参数类型FunctionX,它们都是逆变的.
| 归档时间: |
|
| 查看次数: |
2028 次 |
| 最近记录: |