Lernpfad:Objektorientierte Programmierung mit Java/Vererbung: Unterschied zwischen den Versionen

Zur Navigation springen Zur Suche springen
keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Zeile 11: Zeile 11:
{{Schublade|Es gibt verschiedene Formen wie Rechteck, Dreieck und Quadrat. Jede Form besitzt eine x- und y-Koordinate und eine Richtung. Formen können versetzt und gedreht werden. Rechtecke besitzen zwei Seitenlängen. Bei Quadraten sind beide Seitenlängen gleich. Dreiecke werden über zwei Punkte festgelegt, die auch eine x- und y-Koordinate besitzen. Die dritte Ecke wird durch die Position des Dreiecks festgelegt.}}
{{Schublade|Es gibt verschiedene Formen wie Rechteck, Dreieck und Quadrat. Jede Form besitzt eine x- und y-Koordinate und eine Richtung. Formen können versetzt und gedreht werden. Rechtecke besitzen zwei Seitenlängen. Bei Quadraten sind beide Seitenlängen gleich. Dreiecke werden über zwei Punkte festgelegt, die auch eine x- und y-Koordinate besitzen. Die dritte Ecke wird durch die Position des Dreiecks festgelegt.}}
Ein erstes Implementierungsdiagramm ohne Vererbung könnte so aussehen:
Ein erstes Implementierungsdiagramm ohne Vererbung könnte so aussehen:
<graphviz>
[[Datei:UML Vererbung 1.jpg|center]]
digraph G {
        fontname = "Bitstream Vera Sans"
        fontsize = 10
        rankdir = TB
 
        node [fontname = "Bitstream Vera Sans";fontsize = 10;shape = "record"]
        edge [fontname = "Bitstream Vera Sans";fontsize = 10]
 
Dreieck [label = "{Dreieck|-position: Punkt\l-richtung: double\l-punktB: Punkt\l-punktC: Punkt\l|+Dreieck(pPosition: Punkt, pPunktB: Punkt\l pPunktC: Punkt, pRichtung: double)\l+getPosition(): Punkt\l+setPosition(pPosition: Punkt)\l+getPunktB(): Punkt\l+setPunktB(pPunktB: Punkt)\l+getPunktC(): Punkt\l+setPunktC(pPunktC: Punkt)\l+getRichtung(): double\l+setRichtung(pRichtung: double)\l+versetzen(pX: int, pY: int)\l+drehen(pGrad: double)\l}"]
Rechteck [label = "{Rechteck|-position: Punkt\l-richtung: double\l-a: int\l-b: int\l|+Rechteck(pPosition: Punkt, pA: int\l pB: int, pRichtung: double)\l+getPosition(): Punkt\l+setPosition(pPosition: Punkt)\l+getA(): int\l+setA(pA: int)\l+getB(): int\l+setB(pB: int)\l+getRichtung(): double\l+setRichtung(pRichtung: double)\l+versetzen(pX: int, pY: int)\l+drehen(pGrad: double)\l}"]
Quadrat [label = "{Quadrat|-position: Punkt\l-richtung: double\l-a: int\l|+Quadrat(pPosition: Punkt, pA: int,\l pRichtung: double)\l+getPosition(): Punkt\l+setPosition(pPosition: Punkt)\l+getA(): int\l+setA(pA: int)\l+getRichtung(): double\l+setRichtung(pRichtung: double)\l+versetzen(pX: int, pY: int)\l+drehen(pGrad: double)\l}"]
Punkt [label = "{Punkt|-x: int\l-y : int\l|+Punkt(pX: int, pY: int)\l+getX(): int\l+getY(): int\l+setX(pX: int)\l+setY(pY: int)\l}"]
 
edge [style="dashed",arrowhead="open"]
Dreieck -> Punkt
Rechteck -> Punkt
Quadrat -> Punkt
}
</graphviz>


Es ergeben sich einige Dopplungen bei Eigenschaften und Methoden. Jede Klasse besitzt x- und y-Koordinaten und eine Richtung als Attribut, sowie die Methoden <code>versetzen</code> und <code>drehen</code>. Diese müssten bei der Implementierung jeweils exakt gleich umgesetzt werden, was neben viel Aufwand sehr fehleranfällig ist.
Es ergeben sich einige Dopplungen bei Eigenschaften und Methoden. Jede Klasse besitzt x- und y-Koordinaten und eine Richtung als Attribut, sowie die Methoden <code>versetzen</code> und <code>drehen</code>. Diese müssten bei der Implementierung jeweils exakt gleich umgesetzt werden, was neben viel Aufwand sehr fehleranfällig ist.
Zeile 39: Zeile 20:


Das neue Implementierungsdiagramm sieht so aus:
Das neue Implementierungsdiagramm sieht so aus:
<graphviz>
[[Datei:UML Vererbung 2.jpg|center]]
digraph G {
        fontname = "Bitstream Vera Sans"
        fontsize = 8
        rankdir = BT
 
        node [fontname = "Bitstream Vera Sans";fontsize = 8;shape = "record"]
        edge [fontname = "Bitstream Vera Sans";fontsize = 8]
 
Dreieck [label = "{Dreieck|-punktB: Punkt\l-punktC: Punkt\l|+Dreieck(pPosition: Punkt, pPunktB: Punkt\l pPunktC: Punkt, pRichtung: double)\l+getPunktB(): Punkt\l+setPunktB(pPunktB: Punkt)\l+getPunktC(): Punkt\l+setPunktC(pPunktC: Punkt)\l}"]
Rechteck [label = "{Rechteck|-a: int\l-b: int\l|+Rechteck(pPosition: Punkt, pA: int\l pB: int, pRichtung: double)\l+getA(): int\l+setA(pA: int)\l+getB(): int\l+setB(pB: int)\l}"]
Quadrat [label = "{Quadrat||+Quadrat(pPosition: Punkt, pRichtung: double,\lpA: int)\l}"]
Punkt [label = "{Punkt|-x: int\l-y : int\l|+Punkt(pX: int, pY: int)\l+getX(): int\l+getY(): int\l+setX(pX: int)\l+setY(pY: int)\l}"]
Form [label="{Form|-position: Punkt\l-richtung: double|+Form(pPosition: Punkt, pRichtung: double)\l+getPosition(): Punkt\l+setPosition(pPosition: Punkt)\l+getRichtung(): double\l+setRichtung(pRichtung: double)\l+versetzen(pX: int, pY: int)\l+drehen(pGrad: double)\l}"]
 
edge [style="dashed",arrowhead="open"]
Dreieck -> Punkt
Form -> Punkt
 
edge [arrowhead="empty"]
Quadrat -> Rechteck -> Form
Dreieck -> Form
}
</graphviz>


Folgende Anweisungen sind mit Vererbung korrekt, obwohl der Quelltext der Klasse <code>Quadrat</code> die Methode <code>public void versetzen()</code> nirgendwo explizit enthält.
Folgende Anweisungen sind mit Vererbung korrekt, obwohl der Quelltext der Klasse <code>Quadrat</code> die Methode <code>public void versetzen()</code> nirgendwo explizit enthält.

Navigationsmenü