Supposons que nous ayons:
class B
class A extends B
trait T
Ensuite, il détient:
val a: A with T = new A with T
a.isInstanceOf[B] // result is true !
Est-il juste de dire que la méthode isInstanceOf
vérifie s'il existe au moins un type (pas tous les types) qui correspond au côté droit dans une relation de sous-type?
À première vue, j'ai pensé à une valeur de type A with T
ne peut pas être un sous-type de B
, car A
etT
ne sont pas les deux sous-types de B
. Mais c'est A
oT
est un sous-type de B
- est-ce vrai?
isInstanceOf
recherche s'il existe une entrée correspondante dans la chaîne d'héritage. La chaîne de A with T
inclut A
, B
et T
, donc a.isInstanceOf[B]
doit être vrai.
éditer:
En fait, le code d'octet généré appelle javas instanceof
, donc ce serait a instanceof B
en Java. Un appel un peu plus complexe comme a.isInstanceOf[A with T]
serait (a instanceof A) && (a instanceof T)
.
À première vue, je pensais qu'une valeur de type A avec T ne pouvait pas être un sous-type de B
Il y a deux idées fausses ici. Premièrement, que le type statique d'une instance a une incidence sur le résultat de isInstanceOf
: il n'y en a pas. Pour être clair, lorsque vous faites a.isInstanceOf[B]
, le fait que a
est de type A with T
n'est pas pertinent.
La méthode isInstanceOf
est implémentée au niveau du bytecode par la JVM. Il regarde les informations de classe chaque instance porte, et vérifie si B
une des classes (la classe de l'instance elle-même et ses ancêtres), ou l'une des interfaces implémentées. C'est la relation "est-un": "a est un B".
Techniquement, isInstanceOf
fait partie de la réflexion de Java, où il est appelé instanceof
.
La deuxième idée fausse est que l'héritage peut en quelque sorte supprimer un type parent. Cela n'arrive jamais: l'héritage n'ajoute que des types, ne les supprime jamais. Le type A with T
est un A
, un B
, un T
, un AnyVal
et un Any
. Donc, même si isInstanceOf
a bien regardé le type A with T
, cela reviendrait toujours vrai.