2011-03-18 2 views
28

다음 예제를 사용하여 반공 진성이 유용한 이유를 설명하려고합니다.contavvariance의 예

GUI 프레임 워크를 Widgets, EventsEvent Listeners으로 가정 해 보겠습니다. 하자 Widgets

abstract class Event; 
class KeyEvent extends Event 
class MouseEvent extends Event 

trait EventListener[-E] { def listen(e:E) }

는 다음과 같은 방법을 정의

def addKeyEventListener(listener:EventListener[KeyEvent]) 
def addMouseEventListener(listener:EventListener[MouseEvent]) 

이 방법이 잘되는 만 "특정"이벤트 리스너에 동의합니다. 그러나 나는 또한 "kitchen-sink"청취자를 정의하고 싶습니다. 청취자는 모든 이벤트를 듣고 그러한 청취자를 위의 "청취자 추가"메소드에 전달합니다.

예를 들어, 나는 모든 들어오는 이벤트

class LogEventListener extends EventListener[Event] { 
    def listen(e:Event) { log(event) } 
}

형질 EventListener 우리가 잃지 않고 모든 "리스너를 추가"방법에 LogEventListener를 전달할 수 있습니다 Event에서 contravariant 때문에

를 기록 LogEventListener를 정의하고자하는 그들의 타입 안전.

의미가 있습니까?

+0

+1 좋은 질문, 나쁜 수용율. 슬퍼! – Nishant

답변

6

어쨌든 나에게 의미가 있습니다. 또한 내가 본 가장 직관적 인 예 중 하나입니다. 모든 이벤트를 자연스럽게 들으면서 주요 이벤트 나 마우스 이벤트를들을 수 있습니다.

6

나에게도 의미가 있습니다. 경험적으로 매개 변수화 된 유형 Type[A]은 유형 매개 변수 A에 대해 A의 인스턴스를 수락하여 매개 변수을 수락함으로써 매개 변수를 수락 할 때마다 반올 변해야합니다. 이 스칼라에 정의 된 경우

는 예를 들어, Java 형 Comparator[T]은, contravariant되었을 것이다 : 그것은 모두가 비교할 수 Comparator[String], 그리고 더 많은 개체를 비교할 수로 Comparator[Any]Comparator[String]의 하위 유형이어야합니다. 가장 일반적인 예는 클래스가 모두 반 패턴 인 FunctionX 클래스의 인수 유형입니다.