21. Klassendiagramme Inhaltsverzeichnis 23. XML

22. Mehrfachbeerbung

Wie schon bei ManQ, kann in Java ExtItQ für ItArrayQ und ItListQ gemeinsam implementiert, aber dann (wegen der fehlenden Mehrfachbeerbung) nicht zusammen mit ItArrayQ bzw. ItListQ beerbt werden.

Es gilt generell: Wenn eine Sprache keine Mehrfachbeerbung anbietet, muss sie durch Instanziierung simuliert werden: Statt

class Unter extends Ober1 with Ober2 {}

muss

class Unter extends Ober1 with SchnittstelleVonOber2 {

   var ober2 = new Ober2

… }

oder

class Unter extends Ober2 with SchnittstelleVonOber1 {

   var ober1 = new Ober1

… }

geschrieben werden. Die geerbten Methoden müssen dann mühsam durchgereicht werden:

class Unter extends Ober1 with SchnittstelleVonOber2 {

   var ober2 = new Ober2

   def methode = { // aus Ober2

     ober2.methode }

… }

Typischerweise entscheidet man sich für die bequemere Oberklasse: die, die mehr Methoden vererbt (damit weniger Methoden durchgereicht werden müssen). Wenn eine der Oberklassen abstrakt (bzw. ein Trait) ist, kann sie nicht ausgeprägt werden; dann muss sie erweitert werden. Wenn beide abstrakt sind, muss eine der abstrakten Oberklassen in eine abstrakte und eine konkrete Klasse aufgeteilt werden. Bei mehr als zwei Oberklassen müssen entweder mehrere instanziiert, oder einige auf demselben Wege zusammengeführt werden.

Im Falle von ExtItListQ müssen wir uns zwischen zwei Typen als Oberklasse entscheiden: ItListQ und ExtItQ. Bequemer wäre ItListQ, zumal sie mehr Methoden (alles von Queue und Iterator) implementiert. ExtItQ ist aber abstrakt; obwohl ItListQ ein Trait ist (um eingemischt werden zu können), enthält sie nur konkrete Methoden. Daher kann sie leicht (durch eine leere Erweiterung) instanziiert werden:

/** Extended Queue with iterator and single inheritance */

class ExtItListQ1[E] extends ExtItQ[E] with Queue[E] {

   private val ilq = new ItListQ[E] {} // [1]

   def add(o: E) = ilq.add(o)

   def remove = ilq.remove

   def element = ilq.element

   def clear = ilq.clear

   override def isEmpty = ilq.isEmpty // [2]

   def isFull = ilq.isFull

   def iterator = ilq.iterator }

ExtItArrayQ ohne Mehrfachbeerbung ist wegen des Klassenparameters ein Hauch komplizierter:

class ExtItArrayQ1[E](size: Int) extends ExtItQ[E] with Queue[E] {

   private class ItArrayQ1[E](size: Int) extends ArrayQ[E](size)

     with ItArrayQ[E] {}

   private val iaq = new ItArrayQ1[E](size)

   def add(o: E) = iaq.add(o)

   def remove = iaq.remove

   def element = iaq.element

   def clear = iaq.clear

   override def isEmpty = iaq.isEmpty

   def isFull = iaq.isFull

   def iterator = iaq.iterator }

Die Klasse PersItListQ kann ähnlich ohne Mehrfachbeerbung implementiert werden.

Das Objektdiagramm stellt dar, dass ein Objekt der inneren Klasse ItArrayQ1 einen ArrayQ-Anteil und einen ItArrayQ-(Iterable-) Anteil hat (der den Iterator liefert). Die für den Benutzer instanziierbare Klasse ExtItArrayQ1 enthält neben dem hier programmierten Anteil mit iaq auch den von ExtItQ geerbten Anteil (der die Methoden equals und copy liefert).

Abbildung 43: Einfachbeerbung

In diesem Objektdiagramm stellt das punktierte Quadrat dar, dass das Objekt zwar keine Variable iterator enthält, aber die Methode iterator ein Iterator-Objekt liefert.

21. Klassendiagramme Inhaltsverzeichnis 23. XML

[1] anonyme Erweiterung

[2] override, weil Iterator auch isEmpty enthält


Version: 5. Dezember 2010

© Prof. Solymosi, 2010, Beuth-Hochschule für Technik Berlin