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ę C1
z metodą f()
i klasę C2
ró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 Nothing
rzeczy, 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ć Nothing
jako podtyp wszystkiego według specyfikacji. Z oczywistych powodów Nothing
nie zdefiniowano, aby obejmowało wszystkie klasy załadowane do systemu, ale istotność zdefiniowania Nothing
jako 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.