我正在考虑以下示例来说明为什么逆变是有用的。
让我们考虑一个带有Widgets
、Events
和的 GUI 框架Event Listeners
。
abstract class Event;
class KeyEvent extends Event
class MouseEvent extends Event
trait EventListener[-E] { def listen(e:E) }
让我们Widgets
定义以下方法:
def addKeyEventListener(listener:EventListener[KeyEvent])
def addMouseEventListener(listener:EventListener[MouseEvent])
这些方法只接受“特定”事件侦听器,这很好。但是,我还想定义“厨房水槽”侦听器,它侦听所有事件,并将此类侦听器传递给上面的“添加侦听器”方法。
例如,我想定义LogEventListener
记录所有传入事件
class LogEventListener extends EventListener[Event] {
def listen(e:Event) { log(event) }
}
由于 traitEventListener
是逆变的,Event
我们可以传递LogEventListener
给所有这些“添加侦听器”方法,而不会失去它们的类型安全性。
是否有意义 ?