2012-06-30 9 views
6
scala> class A 
defined class A 

scala> class B {this: A => } 
defined class B 

scala> new B 
<console>:10: error: class B cannot be instantiated because it does not conform 
to its self-type B with A 
      new B 
      ^

klasy B ustawia zaworem do klasy A zatem B klasy (lub podklasy niego) ma przedłużenie klasy A utworzyć egzemplarz B. Ale czy jest to w ogóle możliwe, ponieważ podklasa B może rozszerzyć tylko jedną klasę (i jest to klasa B)?Czy klasa mająca własny typ innej klasy ma sens?

Więc to prowadzi mnie do pytania, czy w ogóle ma sens ogłoszenie klasy własnej klasy innej klasie?

Odpowiedz

10

Masz rację, że ta definicja nie może prowadzić do konkretnej implementacji, ponieważ nie można łączyć dwóch klas, tylko cech. Krótka odpowiedź brzmi "nie", albo powinna być cechą.

Istnieje kilka pytań na temat Stackoverflow dotyczących typów własnych. Dwa użyteczne te są takie:

W drugim pytaniu, nie jest dobra odpowiedź Ben Lings który przytacza następujący fragment z blogu Spiros Tzavellas:

Podsumowując, jeśli chcemy przenosić implementacje metod wewnątrz cech, ryzykujemy zanieczyszczanie interfejsu tych cech za pomocą metod abstrakcyjnych. wspierają wdrażanie konkretnych metod i nie są powiązane z główną odpowiedzialnością tej cechy. Rozwiązaniem tego problemu jest przeniesienie tych abstrakcyjnych metod na inne cechy i wspólne zestawienie cech za pomocą adnotacji typu self i wielokrotnego dziedziczenia.

Na przykład, jeśli A (załóżmy, że jest to cecha, a nie klasa teraz!) Jest rejestratorem. Nie chcesz ujawnić publicznie interfejsu API rejestrowania danych przez A. Dlatego używałbyś typu własnego, a nie mixin. W ramach implementacji B można wywołać interfejs API rejestrowania, ale z zewnątrz nie jest widoczny.


Z drugiej strony, można użyć kompozycję w następującej formie:

trait B { 
    protected def logger: A 
} 

Różnica jest teraz, że

  • B musi odnosić się do logger, gdy chcemy korzystać z jego funkcjonalności
  • podtypy B mają dostęp do logger
  • B i A nie konkurują w przestrzeni nazw (np. może mieć metody o tej samej nazwie bez kolizji)

Powiedziałbym, że self-typy są dość peryferyjną cechą Scali, w wielu przypadkach ich nie potrzebujesz, i masz takie opcje, aby osiągnąć prawie to samo bez własnych typów.

+0

Świetna odpowiedź, dziękuję bardzo. –

Powiązane problemy