2016-12-09 3 views
0

Lassen Sie mich meine Beobachtung in scala über multiple Vererbung erklären -Mehrfachvererbung nicht für Klasse/abstrakte Klasse unterstützt, aber für Merkmal in scala unterstützt. Warum?

Mehrfache Vererbung ist nicht in Scala für Klassen möglich. Ich kann verstehen, diese zu „Diamant Problem“ zurückzuführen ist http://stackoverflow.com/questions/2064880/diamond-problem so unter Code nicht

class High { 
    def confuse(){ 
    println("High::I will confuse you later") 
    } 
} 
class MiddleLeft extends High { 
    override def confuse(){ 
    println("MiddleLeft::I will confuse you later") 
    } 
} 
class MiddleRight extends High{ 
override def confuse(){ 
    println("MiddleRight::I will confuse you later") 
    } 
} 

// Below code does not compile 
class LowLeft extends MiddleRight with MiddleLeft{ 
    def calConfuse(){ 
    confuse() 
    } 
} 

Jetzt haben könnten Züge konkrete Klassen nicht kompiliert. Aber es unterstützt Mehrfachvererbung, weil Reihenfolge, in den Zügen erweitert werden spielt eine Rolle, die das Diamant-Problem zu lösen, so unten Code funktioniert

trait High { 
    def confuse(){ 
    println("High::I will confuse you later") 
    } 
} 
trait MiddleLeft extends High { 
    override def confuse(){ 
    println("MiddleLeft::I will confuse you later") 
    } 
} 
trait MiddleRight extends High{ 
override def confuse(){ 
    println("MiddleRight::I will confuse you later") 
    } 
} 

class LowLeft extends MiddleRight with MiddleLeft{ 
    def calConfuse(){ 
    confuse() 
    } 
} 
class LowRight extends MiddleLeft with MiddleRight{ 
    def calConfuse(){ 
    confuse() 
    } 
} 

object ConfuseTester extends App{ 
    val lowLeft:LowLeft=new LowLeft() 
    lowLeft.confuse() //prints>>>MiddleLeft::I will confuse you later 
    val lowRight:LowRight=new LowRight() 
    lowRight.confuse()//prints>>>MiddleRight::I will confuse you later 
} 

Meine Frage ist, warum die mehrfache Vererbung für Klassen nicht gleiche Strategie folgt wie Zug tut (Ordering wie diese erweitert werden)

+2

Klassen haben Konstrukteure, Merkmale nicht. Es wäre in einigen Fällen unmöglich, beide Konstruktoren zu erfüllen. –

+0

Eigenschaften können "Konstruktoren" (Initialisierer) in Dotty und Scala 2.12 haben. Wenn Sie sich die Einschränkungen anschauen, die Initialisierer im Vergleich zu Klassenkonstruktoren haben, können Sie Hinweise zu den Dingen erhalten, die bei der Mehrfachvererbung für Klassen brechen können. Aber eigentlich ist die Hauptsache: Mehrfachvererbung für Klassen hat eine spezifische Bedeutung, nämlich eine Klasse, die mehrere Oberklassen hat. Das ist nicht was Merkmal-Mixins tun: Merkmal-Mixins haben nur ein * Super-Porträt, sie wissen einfach nicht welches. Die Neudefinition der Klassen-Mehrfachvererbung, um dasselbe wie Merkmals-Mixins zu meinen, ist sicherlich ... –

+0

... möglich, aber es wäre keine Klassen-Mehrfach-Vererbung mehr, es wäre Merkmals-Mixins, und die Klassen wären keine Klassen mehr, sie wären Merkmale oder Mixins und sie immer noch als Klassen zu bezeichnen, würde nur zu Verwirrung führen. Mit MI erscheint eine Klasse * einmal * im Vererbungsbaum (wirklich, eine DAG mit MI) und hat * multiple * Superklassen, ein Merkmal Mixin erscheint * mehrfach * im Vererbungsbaum und hat nur * ein * Supertrait (obwohl an jedem Punkt ein anderer erscheint. Die beiden sind genau zueinander dual. –

Antwort

1

Jede Scala-Klasse wird in eine einzelne JVM-Klasse kompiliert, und JVM unterstützt keine Mehrfachvererbung für Klassen.

+0

Das ist ein Implementierungsdetail einer bestimmten Implementierung von Scala. Z.B. Scala.js kompiliert überhaupt nicht zu Klassen, hat aber die gleiche Einschränkung. Scala-nativ ist völlig frei, ein Kodierungsschema für gewünschte Merkmale und Klassen zu definieren, hat aber die gleiche Einschränkung. Außerdem können Sie Eigenschaften mit Scala-JVM kompilieren, auch wenn die JVM keine Eigenschaften besitzt. Daher ist es sicher möglich, eine ähnliche Kodierung für Klassen zu wählen. –

+0

Für das erste Argument: Soweit ich weiß, war die einzige Implementierung fast so alt wie JVM Scala CLR Scala (jetzt aufgegeben), und das gleiche Argument würde dort gelten. Scala.js und Scala-native sind beide lange nach der Festlegung dieser Einschränkung in der Scala-Spezifikation erschienen und haben keinen Grund, die Kompatibilität in dieser spezifischen Hinsicht aktiv zu brechen (und konnten JVM Scala nicht so oft wie bisher verwenden wenn sie es taten). –

+0

Für die Sekunde: Ich erwarte, dass, wenn Odersky und seine Mitautoren _had_ mit einer solchen Kodierung, und ohne unerwünschte Beschränkungen gekommen wären, es verwendet worden wäre und vielleicht Scala nicht einmal Eigenschaften gehabt hätte. Aber das taten sie nicht, also war es nicht so. Dies bedeutet nicht, dass es unmöglich ist, aber es scheint sicherlich schwer zu erreichen. –

Verwandte Themen