Scala Bytes: Stapelweise Traits
Ein zweiter Trait
Man ist natürlich nicht auf einen einzigen Trait beschränkt. Die Kombinierbarkeit als Mixin ist ja gerade eine der Stärken von Traits, und das gilt ganz besonders für Stackable Traits – daher rührt auch ihr Name. Erstellen wir also einen zweiten Trait für IntSets. Dieser soll bei add()und remove()das entsprechende Element nicht hart hinzufügen bzw. entfernen, sondern seinen Zustand jeweils invertieren („XOR“):
trait Xor extends IntSet { abstract override def add(i: Int) = xor(i) abstract override def remove(i: Int) = xor(i) def xor(i: Int) = if (contains(i)) super.remove(i) else super.add(i) }
Hier sind die super-Aufrufe in einer separaten Methode, um Codeduplizierung zu vermeiden. Das funktioniert problemlos. Alle Methoden, die mit super. aufgerufen werden, müssen aber im Trait als abstract override definiert sein. Wir könnten also nicht einfach die remove-Implementierung streichen, weil wir super.remove() aufrufen wollen. Wenn wir remove unverändert lassen wollten, müssten wir den Aufruf explizit durchreichen:
abstract override def remove(i: Int) = super.remove(i)
Jedenfalls können wir jetzt unsere Traits kombinieren und auf einfache Weise ein IntSet erzeugen, das sowohl die höchsten Bits abschneidet als auch XOR-Semantik hat:
val s = new SimpleIntSet with Modulo with Xor
Fazit
Man kann mithilfe von Traits Mixins erstellen, die Methodenaufrufe bei Bedarf an die nächste innere Implementierung weiterleiten. Dadurch kann man sehr modularen Code schreiben, der in der Verwendung gut lesbar und explizit ist.
Hinterlasse einen Kommentar