2012-07-02 9 views
20

assumere, abbiamo:Come funziona `isInstanceOf`?

class B 
class A extends B 
trait T 

Allora vale:

val a: A with T = new A with T 
a.isInstanceOf[B] // result is true ! 

è giusto dire, le isInstanceOf controlli di metodo, se v'è almeno un tipo (non tutti i tipi), che corrisponde il lato destro in una relazione di sottotipo?

A prima vista, ho pensato un valore di tipo A with T non può essere un sottotipo di B, perché AeT non sono due sottotipi di B. Ma è AoT è un sottotipo di B - è vero?

+4

Sì, è tutto. – Nicolas

+0

Ecco una breve panoramica sull'uguaglianza degli oggetti http://joelabrahamsson.com/learning-scala-part-eight-scalas-type-hierarchy-and-object-equality/ – Jaider

risposta

30

isInstanceOf controlla se esiste una voce corrispondente nella catena di ereditarietà. La catena di A with T include A, B e T, pertanto a.isInstanceOf[B] deve essere true.

edit:

In realtà il bytecode generato chiama Javas instanceof, quindi sarebbe a instanceof B in java. Una chiamata un po 'più complessa come a.isInstanceOf[A with T] sarebbe (a instanceof A) && (a instanceof T).

+1

Grazie per le informazioni di base, che hanno aiutato molto.Sai dove posso trovare più informazioni di base sul metodo 'isInstanceOf' di Scala? L'API di Scala non ne parla molto. –

+0

Non c'è molto da dire. È solo 'instanceof'. – drexin

10

A prima vista, ho pensato un valore di tipo A con T non può essere una sottotipo di B

C'è sono due idee sbagliate qui. Innanzitutto, il tipo statico di un'istanza influisce sul risultato di isInstanceOf: non ce n'è. Per essere chiari, quando si fa a.isInstanceOf[B], il fatto che a sia di tipo A with Tnon è rilevante.

Il metodo isInstanceOf è implementato a livello di bytecode da JVM. Analizza le informazioni sulla classe ogni istanza contiene e controlla se B una delle classi (la classe dell'istanza stessa e dei relativi antenati) o una delle interfacce implementate. Questa è la relazione "è-a": "a is a B".

Tecnicamente, isInstanceOf fa parte della riflessione di Java, dove è noto come instanceof.

Il secondo malinteso è che l'eredità può in qualche modo rimuovere un tipo genitore. Non succede mai: l'ereditarietà aggiunge solo tipi, mai li rimuove. Il tipo A with T è un A, uno B, uno T, uno AnyVal e uno Any. Quindi, anche se isInstanceOf ha guardato il tipo A with T, sarebbe ancora restituito true.

+0

Sai come posso provare che 'Null' e' Nothing' sono sottotipi di tutte le cose nel REPL? '" A ".isInstanceOf [Null]' errori? come fa 'Nothing'? Immagino che abbia senso; per esempio "un'istanza di null" non funzionerebbe in Java. Devo solo prendere la parola doc per questo ?! – Toby

+0

@Toby 'Nothing' non esiste in Java, poiché tratta classi e primitive e cose distinte, e' instanceof' si riferisce solo al primo. Inoltre, 'Null' non esiste né in Java, che non ha il concetto di un" fondo ". –