2009-07-05 13 views
42

Szybka uwaga: Przykłady z samouczka: Scala for Java Refugees Part 5: Traits and Types.Mieszanie wielu cech w Scala

Załóżmy, że mam cechy Student, Worker, Underpaid i Young.

Jak mogę zadeklarować klasę (nie instancja), CollegeStudent, z wszystkimi tymi cechami?

Uwaga: Jestem świadomy przypadkach simplests, takich jak CollegeStudent jedną lub dwie cechy:

class CollegeStudent extends Student with Worker 
+1

??? zadając pytanie, a następnie zgłaszając się –

+0

Próbowałem już raz z Eclipse dawno temu i to nie działało. Po aktualizacji i napisaniu testu pomyślałem: "Może spróbuję czegoś i zobaczę, czy mogę znaleźć to sam". –

+14

@Peter: nie ma nic złego w pytaniu i odpowiadaniu, o ile jest to prawidłowe pytanie. – Grundlefleck

Odpowiedz

86

To jest łatwe, gdy deklarując klasę po prostu użyć „z” keyword jak często jak chcesz

class CollegeStudent extends Student with Worker with Underpaid with Young 

kolejność cech może być ważne, jeśli cecha zmienia zachowanie klasy, to wszystko zależy od cech używasz.

Także, jeśli nie chcemy mieć klasy, który zawsze wykorzystuje te same cechy można wykorzystać je później:

class CollegeStudent extends Student 
new CollegeStudent with Worker with Underpaid with NotSoYoungAnymore 
+1

Zmiana zachowania oznacza wywołanie metody cechy, która jest zaimplementowana i ma tę samą nazwę w wielu cechach. Tak więc w oparciu o kolejność cech nazwałaby tę metodę. –

7

Myślę, że bardzo ważne jest, aby wyjaśnić nie tylko składnię, ale także jaką rolę odgrywa kolejność znaków. Znalazłem wyjaśnienie w Jason Swartz's Learning Scala (strona 177) dość rozjaśniające.

  • Klasa Scala może rozszerzać wiele cech jednocześnie, ale klasy JVM mogą obejmować tylko jedną klasę nadrzędną. Kompilator Scala rozwiązuje to, tworząc "kopie każdej cechy, aby utworzyć wysoką, jednokolumnową hierarchię klasy i cech", proces znany jako linearyzacja .

  • W tym kontekście, rozszerzając wiele cech z identycznymi nazwami pól nie powiedzie się skompilować, dokładnie tak samo „jakbyś rozszerzenie klasy i zapewniając własną wersję metody, ale nie udało się dodać słowa kluczowego override” .

A ponieważ określa on kształt drzewa dziedziczenia, porządek linearyzacji jest rzeczywiście jednym z bardzo ważnych pytań do rozważenia. Na przykład: class D extends A with B with C (gdzie A jest klasą i B i C są cechami) stałoby się class D extends C extends B extends A. Poniżej kilka linii, a także z książki, ilustrują, że doskonale:

trait Base { override def toString = "Base" } 
class A extends Base { override def toString = "A->" + super.toString } 
trait B extends Base { override def toString = "B->" + super.toString } 
trait C extends Base { override def toString = "C->" + super.toString } 
class D extends A with B with C { override def toString = "D->" + super.toString } 

Wywołanie new D() byłoby mieć REPL wydrukować następujące:

D->C->B->A->Base 

który doskonale odzwierciedla strukturę liniową wykresu spadków .

Powiązane problemy