2016-11-20 5 views
1

Ich lerne Clojure und ich frage mich, wie man mit OO-ähnlichen Unterklassen in Clojure umgehen kann. Zum Beispiel: eine abstrakte Hauptklasse, zwei abstrakte Unterklassen (jede definiert einige Funktionen neu) und auf der dritten Ebene abschließende Unterklassen, die "Objekte" erzeugen, die in den Funktionen verwendet werden. Keine Ahnung, wie das geht. Ich habe es jedoch mit einer abstrakten Klasse zu einer Kindklasse geschafft, mit Defrotocol und Defrecord. Aber ich kann ein Protokoll nicht innerhalb eines anderen implementieren. DankeUnterklassen in clojure

+1

Erstellen Sie ein Protokoll, das als abstrakte Basisklasse fungiert, und definieren Sie dann Protokolle, die jede neue "Ebene" darstellen. Datensätze können mehr als ein Protokoll implementieren, also sollte dies funktionieren. – Carcigenicate

+0

Vielleicht relevant: http://clojure.org/reference/multimethods (besonders der Teil, dass Clojure den traditionellen OO-Ansatz vermeidet, aber Sie können Polymorphismus auf verschiedene Arten erreichen). –

+0

@Carcigenicate die Sache ist, ich brauche die Datensätze, um nur ein Protokoll zu implementieren, die das Basisprotokoll mitbringen wird. Zum Beispiel: Ich habe sieben Klassen in dieser Reihenfolge: A-> B A-> C B -> D B-> E C-> F C-> G Und für B und C die sie benötigen, einige Methoden von A – juanimoli

Antwort

6

Sie brauchen keine Klassen oder Unterklassen. Stellen Sie Ihre Daten als Karten mit Attributen dar. Die "Unterklassen" könnten mehr Attribute haben.

Wenn Sie eine Funktion haben, die auf Attribut variiert, dann verwenden Sie entweder bedingte Logik basierend auf Attribut (if, cond, etc) oder verwenden Polymorphismus basierend auf Multimethoden oder Protokolle, wenn Sie wirklich brauchen.

In den Worten der Matrix gibt es keinen Löffel.

+0

Ich muss in diesen Tagen wirklich in Multimethoden schauen. Ich schreibe seit fast einem halben Jahr Clojure und muss sie noch berühren. – Carcigenicate

2

Sie können mit Protokollen wie dieses Erbe tun:

(extend <subtype> 
    <protocol> 
    (merge (get-in <protocol> [:impls <basetype>]) 
     <map-of-redefined-methods>)) 

Multimethoden bieten direkte Unterstützung für die Vererbung mit derive.

Aktuelle Java-Unterklassenbeziehungen können mit dem Schlüsselwort :extends zu gen-class angegeben werden. Dies ist jedoch ausschließlich für Java Interop gedacht.

Generell lohnt es sich zu prüfen, ob Sie wirklich Vererbung benötigen. Es ist normalerweise nicht die bevorzugte Methode der Modellierung in Clojure.