Kiedy mówi, że Scala nie obsługuje wielokrotnego dziedziczenia, wówczas odnosi się do dziedziczenia implementacji metody wiele razy. Oczywiście można zaimplementować wiele interfejsów / cech w klasie, a nawet zdefiniować tę samą metodę, ale nie występuje konflikt między różnymi implementacjami z powodu linearyzacji cechy.
Ogólnie, jeśli masz klasę C1z metodą f()i klasę C2również z metodą f(), to wielokrotne dziedziczenie oznacza, że możesz w jakiś sposób odziedziczyć obie implementacje f(). Może to prowadzić do różnych problemów, które Scala rozwiązuje, pozwalając ci odziedziczyć po jednej klasie, aw przypadku wielu cech, wybierając jedną implementację na podstawie kolejności cech.
Co do Nothingrzeczy, są naprawdę proste, ponieważ nic nie ma zdefiniowanych atrybutów ani metod. Więc nie możesz mieć żadnych konfliktów spadkowych. Ale zakładam, że większość twoich niespodzianek wynika z innego zrozumienia wielokrotnego dziedziczenia.
Kiedy zrozumiesz, że linearyzacja cech skutecznie eliminuje jakąkolwiek dwuznaczność dziedziczenia, i że nie mówimy o dziedziczeniu z wielu cech jako wielokrotnego dziedziczenia z tego powodu, powinieneś być w porządku.
Jak to się dzieje: kompilator jest ostatecznie za to odpowiedzialny. Zobacz specyfikację języka Scala w rozdziale 3.5.2, która obejmuje między innymi:
For every type constructor T (with any number of type parameters), scala.Nothing <: T <: scala.Any.
Innymi słowy, jeśli chcesz poprawnie wdrożyć kompilator, musi on obsługiwać Nothingjako podtyp wszystkiego według specyfikacji. Z oczywistych powodów Nothingnie zdefiniowano, aby obejmowało wszystkie klasy załadowane do systemu, ale istotność zdefiniowania Nothingjako podtyp jest ograniczona do wszystkich miejsc, w których istotne jest podtypowanie.
Ważną kwestią jest tutaj to, że nie istnieje żadna instancja typu Nothing, dlatego jej leczenie jest ściśle ograniczone do sprawdzania typu, co leży w sferze kompilatora.