2017-10-04 14 views
0

Je trouve un résultat étrange dans le code suivant.Scala override val dans le constructeur

object Practice { 
    class A(val seq: Seq[Int]){ 
    println(f, seq) 
    def f: Seq[Int] = seq 
    } 

    class B(override val seq: collection.mutable.WrappedArray[Int]) extends A(null) 

    def main(args: Array[String]): Unit = { 
    new B(Array(3,4,2)) 
    } 
} 

Le résultat de l'impression est "(WrappedArray (3, 4, 2), null)", ce qui signifie seq et f sont différents! Pourquoi?

Répondre

2

Le "corps" de la classe scala est en fait le corps du constructeur en Java. Quelque chose comme public A(seq: Seq) { this.seq = seq; prinltn(f(), seq); }

Ceci est exécuté lors de la construction de B, lorsqu'il appelle A(null), et imprime la valeur du paramètre, qui est null. Le paramètre masque le membre.

Essayez de changer la définition de A à quelque chose comme ceci:

class A(_seq: Seq[Int]){ 
    println(f, seq) 
    val seq: Seq[Int] = _seq 
    def f: Seq[Int] = seq 
} 

Maintenant, new B(...) imprimera deux valeurs identiques.

La prise de ceci est - ne pas surcharger vals. Ce n'est presque jamais nécessaire et, comme vous pouvez le voir, peut-être plus compliqué qu'il n'y paraît.

Si val est un paramètre de super-classe, vous pouvez toujours simplement passer la valeur correcte lors de la construction de la sous-classe plutôt que de la redéfinition. Si ce n'est pas un paramètre, faites-en un def dans la superclasse.