2017-10-04 11 views
0

Ich finde ein seltsames Ergebnis im folgenden Code.Scala override val im Konstruktor

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)) 
    } 
} 

Das Druckergebnis ist "(WrappedArray (3, 4, 2), null)", was bedeutet, und seqf verschieden sind! Warum?

Antwort

2

Der "Körper" der Scala-Klasse ist eigentlich der Körper des Konstruktors in Java. So etwas wie public A(seq: Seq) { this.seq = seq; prinltn(f(), seq); }

Das während B Konstruktion ausgeführt wird, wenn es A(null) Anrufe und gibt den Wert des Parameters, der null ist. Der Parameter maskiert das Mitglied.

Versuchen Sie, die Definition von A zu so etwas wie dies zu ändern:

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

Nun new B(...) zwei identische Werte gedruckt werden.

Der weg von diesem ist - überschreiben Sie nicht Vals. Es ist fast nie notwendig, und, wie Sie sehen können, kann schwieriger sein, als es aussieht.

Wenn val ein Superklassenparameter ist, können Sie immer den richtigen Wert übergeben, wenn Sie die Unterklasse konstruieren und nicht überschreiben. Wenn es kein Parameter ist, machen Sie es einfach zu einem def in der Oberklasse.