2012-01-01 7 views
8

chciałbym zrobić coś takiego (przykład jest uproszczony, ale zawiera wszystkie istotne elementy):zręcznościowe - wystawienie Public Sub-członek prywatnej członka z niestandardowego typu

class Master 
{ 
    type DataType = Int 
    var counter : DataType = 0 
} 

class Slave(private val master : Master) 
{ 
    val counter = master.counter // (*) 
} 

i tutaj (*) otrzymuję błąd:

private value master escapes its defining scope as part of type Slave.this.master.DataType

val counter = master.counter

rozumiem błąd, ale ja nie rozumiem powodu - typ jest częścią klasy Master, a nie obiektu master, więc ważne jest, jeśli klasa jest prywatny, nie obiekt. Cóż, przynajmniej teoretycznie.

Łatwo jest dokonać szybkiego rozwiązania:

val counter : Master#DataType = master.counter 

Ale wierzę, że jest to jawne wersja dokładnie tego samego kodu, jak poprzednio, to „tylko” zajmuje więcej pisać. Czy to jest zatem cecha?

PYTANIE:

Czy typ (tutaj TypDanych) zależy od obiektu, a nie klasa (czyli definicja typu za instancji klasy) w Scala?

Odpowiedz

14

Mylisz się, gdy myślisz

this is an explicit version of the exactly same code as before

Master#DataType i master.DataType dwa różne typy.

master.DataType to typy instancji DataType, które mają zewnętrzny obiekt master. Innymi słowy, dokładnie to, o co pytasz, ale oczywiście jest to część tego typu, a typ nie może być ujawniony, jeśli nie jest on zdefiniowany jako master.

Master#DataType to typ każdej instancji DataType dla dowolnego obiektu zewnętrznego (odpowiednik Master.DataType w Javie).

odpowiedzieć na komentarz:

członkowie typu mogą być przesłonięte w podklasie (w tym anonimowym podklasy zawierającego tylko jeden obiekt), ale tylko przez typ zgodny. I w twoim przykładzie DataType jest już konkretny w Master, więc jedyną zgodną klasą z nim jest. Więc coś

val a = new Master { 
    override type DataType = String 
} 

nie typecheck, który ma sens: chcesz dostać var counter: String = 0, co jest nonsensem. Jednak będzie działać (ale nie będzie zbyt przydatny).

Więc tylko ma sens zastąpić streszczenie członków typu. Są one jednak sprawdzane typowo w taki sam sposób, jak klasy wewnętrzne, więc a.DataType nie jest ogólnie uznawany za taki sam jak b.DataType - nawet jeśli w rzeczywistości nie mogą być różne!

+0

Dziękuję, więc jeśli dobrze to rozumiem (jednak nie przeczytałem tego w "Programowaniu w Scali", wierzę - a może poślizgnęło się), można zdefiniować typ dla każdej klasy, nie tylko dla każdej klasy . – greenoldman

+0

Dziękuję za aktualizację, jest to bardzo cenne, niestety nie mogę przegłosować twojego postu więcej niż 1 :-) – greenoldman

+0

Jest to jedna z przydatnych rzeczy w Scali, która może być "gotcha", gdy pochodzi z innych języków OOP. Bardzo zwięzła odpowiedź; warte mojego upwote;). – TechNeilogy

Powiązane problemy