7
votes

Scala: traits de mélange avec des champs privés

Ce n'est pas une grande question, c'est plutôt mon excitation que c'est possible du tout! J'ai écrit ce petit exemple pour prouver le contraire - je m'attendais à une erreur de compilateur ou à l'une des valeurs (111 ou 222, je n'étais pas sûr). XXX

Pourquoi v est remplacé? Bien sûr, cela ne fonctionne que tant que v s sont privés, mais toujours.


0 commentaires

3 Réponses :


1
votes

Les membres privés et les méthodes ne peuvent pas être remplacés. Il est d'empêcher les changements de comportement de classe injectés par des descendants. Le concept ici est très similaire à C ++ un - chaque ancêtre détient sa propre copie de membres jusqu'à ce qu'une méthode spéciale (héritage virtuel, par exemple) soit invoquée.


0 commentaires

15
votes

Étant donné que les traits ne sont pas seulement des interfaces, ils ont besoin d'un moyen de stocker leur état interne. Mais ils doivent être compatibles avec des interfaces - alors que font-ils? Ils créent des accesseurs pour ce qui ressemble à un champ (comme vous pouvez le voir (entre autres (entre autres) avec javap -l -s -c -c -private sur les fichiers de classe): xxx

puis créez une classe de mise en œuvre contenant des méthodes statiques pour implémenter la fonctionnalité: xxx

maintenant, espérons-le, il est clair que ceux-ci seraient distincts par défaut puisque ces Les méthodes générées ont le nom du trait au nom de la méthode . Et lorsque nous examinons la mise en œuvre dans T12 : xxx

Vous pouvez voir qu'il remplit simplement ce qui est nécessaire pour chaque trait spécifique. Maintenant, la question est - comment les traits jamais écrasent mutuellement? Ils semblent être complètement séparés! C'est le travail du compilateur. Si quelque chose est privé c'est caché et ne peut pas être remplacé, donc peu importe qu'une autre chose (privée) a le même nom. Mais si ce n'est pas le cas, le compilateur se plaint d'une collision: xxx

Parce que maintenant, il n'utilise pas les noms secrètes mutilés avec le nom de trait incorporé. (Observez que getvaluet1 n'est pas géré dans cet exemple.)


2 commentaires

Bonne réponse. Une légère correction - t1 $ classe s'appelle la classe de mise en œuvre.


En effet - une classe d'accompagnement est autre chose. Fixé.



6
votes

Ce n'est pas une propriété particulière aux traits. Par exemple:

scala> class X {
     |   private val v = 111
     |   def getX = v
     | }
defined class X

scala> class Y extends X {
     |   private val v = 222
     |   def getY = v
     | }
defined class Y

scala> new Y
res0: Y = Y@5ca801b0

scala> res0.getX
res1: Int = 111

scala> res0.getY
res2: Int = 222


2 commentaires

Maintenant, je suis un peu gêné d'être tellement excitée d'une telle chose triviale :) Je suppose que je venais de trop se concentrer sur les traits de voir la photo plus large.


@Vilius Eh bien, il regarde trivial du côté Scala. Quand l'un vient de Java, qui est si plein de limitations, il a l'air spécial.