2011-10-19 16 views
8

Il codice seguente sostiene che Jack è impiegato nella costruzione, ma Jane è l'ennesima vittima dell'economia ruvida:Scala: Corrispondenza classi case

abstract class Person(name: String) { 

    case class Student(name: String, major: String) extends Person(name) 

    override def toString(): String = this match { 
    case Student(name, major) => name + " studies " + major 
    case Worker(name, occupation) => name + " does " + occupation 
    case _ => name + " is unemployed" 
    } 
} 

case class Worker(name: String, job: String) extends Person(name) 

object Narrator extends Person("Jake") { 
    def main(args: Array[String]) { 
    var friend: Person = new Student("Jane", "biology") 
    println("My friend " + friend) //outputs "Jane is unemployed" 
    friend = new Worker("Jack", "construction") 
    println("My friend " + friend) //outputs "Jack does construction" 
    } 
} 

Perché la partita non riescono a riconoscere Jane come studente?

risposta

4

Emil è del tutto corretto, ma ecco un esempio per chiarire:

scala> case class A(a: String) { 
    | case class B(b: String) 
    | def who(obj: Any) = obj match { 
    |  case B(b) => println("I'm A("+a+").B("+b+").") 
    |  case b: A#B => println("I'm B("+b+") from some A") 
    |  case other => println("Who am I?") 
    | } 
    | } 
defined class A 

scala> val a1 = A("a1") 
a1: A = A(a1) 

scala> val a2 = A("a2") 
a2: A = A(a2) 

scala> val b1= a1.B("b1") 
b1: a1.B = B(b1) 

scala> val b2 = a2.B("b2") 
b2: a2.B = B(b2) 

scala> a1 who b1 
I'm A(a1).B(b1). 

scala> a1 who b2 
I'm B(B(b2)) from some A 

Per essere più precisi, questa linea:

case Student(name, major) => name + " studies " + major 

significa veramente

case this.Student(name, major) => name + " studies " + major 

Purtroppo , mentre Jane è stata istanziata su Jake, this nel caso di Jane sta indicando Jane stessa .

5

Quello che credo stia succedendo qui è che la classe di case Student viene dichiarata all'interno di Person. Quindi lo case Student nello toString corrisponderà solo a Student s che fanno parte di una particolare istanza Person.

Se si sposta il case class Student ad essere parallela alla case class Worker (e quindi rimuovere il superfluo extends Person("Jake") da object Narrator ... che è solo lì in modo che il new Student ha finito per essere un Person$Student specifico per Jake), troverete Jane fa anzi studia la biologia.

+0

Puoi chiarire cosa intendi per "una particolare istanza di Persona"? – divider

+0

Qualcuno sa se questo comportamento è documentato ovunque? –

+0

@divider: 'friend' è un' Narrator.Person', ma non un 'amico.Persona'. –

Problemi correlati