29 votes

Exemple de contravariance

Je pense à l'exemple suivant pour illustrer pourquoi la contravariance est utile.

Prenons l'exemple d'un GUI cadre avec Widgets, Events, et Event Listeners.

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

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

Laissez - Widgets définir les méthodes suivantes:

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

Ces méthodes n'accepter qu' "spécifique" des écouteurs d'événement, ce qui est bien. Cependant, je voudrais définir aussi "cuisine-évier" les auditeurs, qui sont à l'écoute de tous les événements, et de transmettre les auditeurs à "ajouter un listener" méthodes ci-dessus.

Par exemple, je voudrais définir LogEventListener pour le journal de tous les événements entrants

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

Depuis le trait EventListener est contravariant en Event , nous pouvons passer l' LogEventListener de toutes les personnes "ajouter un listener" méthodes sans perdre leur type de sécurité.

Est-il judicieux ?

7voto

Daniel C. Sobral Points 159554

Cela a du sens pour moi, de toute façon. Et c'est aussi l'un des exemples les plus intuitifs que j'ai vus: quelque chose qui écoute naturellement tous les événements écoutera les événements clés ou les événements de souris.

7voto

Jean-Philippe Pellet Points 25240

Fait sens pour moi aussi. En règle générale, un paramétrées type Type[A] devrait être contravariant à l'égard de son paramètre de type A chaque fois qu'il est censé accepter les instances de l' A de faire quelque chose avec eux par des moyens de les accepter en tant que paramètres.

Par exemple, le type Java, Comparator[T], si elle avait été définie en Scala, aurait été contravariant: un Comparator[Any] devrait être un sous-type d' Comparator[String], comme on peut le comparer tous les objets d'un Comparator[String] peut comparer, et plus encore. Le plus grand exemple est l'argument types de l' FunctionX classes, qui sont tous contravariant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X