2011-10-19 35 views
8

Các mã sau đây tuyên bố rằng Jack được sử dụng trong xây dựng, nhưng Jane lại là một nạn nhân của nền kinh tế khó khăn:Scala: Kết hợp các lớp trường hợp

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

Tại sao trận đấu thất bại trong việc nhận ra Jane là một sinh viên?

Trả lời

4

Emil là hoàn toàn đúng, nhưng đây là một ví dụ để làm cho nó rõ ràng:

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 

Để được chính xác hơn, dòng này:

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

thực sự có nghĩa

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

Thật không may , trong khi Jane đã được instantiated trên Jake, this trong trường hợp của Jane là chỉ Jane mình .

5

Điều tôi tin đang xảy ra ở đây là lớp trường hợp Student đang được khai báo bên trong số Person. Do đó, case Student trong các toString sẽ chỉ khớp với Student s là một phần của phiên bản Person cụ thể.

Nếu bạn di chuyển case class Student là song song với case class Worker (và sau đó loại bỏ không cần thiết extends Person("Jake") từ object Narrator ... mà chỉ có để các new Student vết thương lên được một Person$Student cụ thể đối với Jake), bạn sẽ tìm thấy Jane làm thực sự nghiên cứu sinh học.

+0

Bạn có thể làm rõ ý của mình bằng "một cá thể Cá nhân cụ thể" không? – divider

+0

Bất cứ ai cũng biết nếu hành vi này được ghi lại ở bất kỳ đâu? –

+0

@divider: 'friend' là một' Narrator.Person', nhưng không phải là 'friend.Person'. –

Các vấn đề liên quan