Lorsqu'il dit que Scala ne prend pas en charge l'héritage multiple, il fait référence à l'héritage d'une implémentation de méthode plusieurs fois. Bien sûr, vous pouvez implémenter plusieurs interfaces / traits dans une classe, et ils peuvent même définir la même méthode, mais vous n'obtenez pas de conflit entre les différentes implémentations en raison de la linéarisation des traits.
En général, si vous avez une classe C1
avec une méthode f()
et une classe C2
également avec une méthode f()
, l'héritage multiple signifie que vous pouvez en quelque sorte hériter des deux implémentations de f()
. Cela peut entraîner divers problèmes, que Scala résout en ne vous laissant hériter que d'une seule classe et en cas de traits multiples en sélectionnant une implémentation en fonction de l'ordre des traits.
Quant aux Nothing
choses sont vraiment simples, car rien n'a d'attributs ou de méthodes définis. Vous ne pouvez donc pas avoir de conflits d'héritage. Mais je suppose que la majeure partie de votre surprise vient d'une compréhension différente de l'héritage multiple.
Une fois que vous comprenez que la linéarisation des traits élimine efficacement toute ambiguïté de l'héritage, et que nous ne faisons pas référence à l'héritage de plusieurs traits comme étant un héritage multiple à cause de cela, alors tout va bien.
Quant à la façon dont cela est réalisé: le compilateur est finalement responsable de cela. Voir la conformité à la spécification 3.5.2 du langage Scala , qui comprend, entre autres propriétés:
For every type constructor T (with any number of type parameters), scala.Nothing <: T <: scala.Any.
Ou en d'autres termes, si vous voulez implémenter un compilateur correctement, il doit le gérer Nothing
comme un sous-type de tout par spécification. Pour des raisons évidentes, il Nothing
n'est pas défini pour s'étendre à toutes les classes chargées dans le système, mais la pertinence de la définition en Nothing
tant que sous-type est limitée à tous les endroits où le sous-typage est pertinent.
Un point important ici est qu'il n'existe aucune instance de type Nothing
, par conséquent, son traitement est strictement limité à la vérification de type, qui est entièrement du domaine du compilateur.