Aufgabe 12 - Formen und Flächen
Aufgabe 12 - Formen und Flächen
Abschnitt betitelt „Aufgabe 12 - Formen und Flächen“Worum geht es?
Abschnitt betitelt „Worum geht es?“Der Klassiker des Polymorphismus: verschiedene geometrische Formen, ein gemeinsamer Vertrag als abstrakte Basisklasse, und ein Programm, das erweiterbar bleibt, ohne dass bestehender Code angefasst wird (siehe Kapitel Polymorphismus und Interfaces). Der Erweiterbarkeits-Beweis in Teil C ist das Herzstück der Übung: Sie erleben das Open-Closed-Prinzip nicht als Vokabel, sondern als überprüfbare Eigenschaft Ihres eigenen Codes.
Was Sie dafür brauchen
Abschnitt betitelt „Was Sie dafür brauchen“- Kapitel Polymorphismus und Interfaces (
abc,@abstractmethod, Open-Closed-Prinzip) und Kapitel Vererbung. - Python (
abc,math), VS Code.
Welche Kompetenzen Sie erwerben und zeigen
Abschnitt betitelt „Welche Kompetenzen Sie erwerben und zeigen“- Sie definieren Verträge als abstrakte Basisklassen und implementieren sie.
- Sie schreiben Funktionen, die ausschließlich gegen den Vertrag programmiert sind.
- Sie weisen die Erweiterbarkeit eines Entwurfs experimentell nach.
Pädagogische Einordnung
Abschnitt betitelt „Pädagogische Einordnung“- Reproduktion: die
abc-Syntax wiedergeben und den Vertrag nach Vorgabe erstellen (Teil A). - Reorganisation und Transfer: den Vertrag auf mehrere konkrete Klassen übertragen und polymorphe Funktionen entwickeln (Teile B und C).
- Reflexion, Problemlösung und Urteilsbildung: eine heikle Vererbungsfrage (Quadrat und Rechteck) untersuchen und ein begründetes Urteil fällen (Teil D).
Arbeitsaufträge
Abschnitt betitelt „Arbeitsaufträge“Die Übung ist auf etwa zwei Stunden ausgelegt. Teil D ist der Expertenteil.
Teil A - Der Vertrag
Abschnitt betitelt „Teil A - Der Vertrag“- Definieren Sie die abstrakte Klasse
Shape(erbt vonABC) mit den abstrakten Methodenarea()undperimeter()sowie der konkreten Methodedescribe(), die etwa"Circle: area 12.57, perimeter 12.57"liefert und dafür die abstrakten Methoden aufruft (type(self).__name__liefert den Klassennamen). - Versuchen Sie,
Shape()direkt zu instanzieren, und notieren Sie die exakte Fehlermeldung. Erklären Sie in einem Satz, warum dieses Verbot erwünscht ist. - Legen Sie eine leere Subklasse
Circle(Shape)an (noch ohne Methoden) und versuchen Sie, sie zu instanzieren. Was meldet Python, und was sagt Ihnen der Zeitpunkt der Meldung?
Teil B - Die Implementierungen
Abschnitt betitelt „Teil B - Die Implementierungen“- Implementieren Sie
Circle(radius),Rectangle(width, height)undTriangle(a, b, c). Für die Dreiecksfläche recherchieren Sie die Formel von Heron. - Ungültige Maße lehnen die Konstruktoren ab: negative oder Null-Werte sowie eine verletzte Dreiecksungleichung führen zu einem
raise ValueError(...)mit aussagekräftiger Meldung. - Prüfen Sie jede Klasse mit einem bekannten Wert (etwa Kreis mit Radius 1: Fläche rund 3.1416; Rechteck 3 mal 4: Fläche 12, Umfang 14).
Teil C - Das polymorphe Programm
Abschnitt betitelt „Teil C - Das polymorphe Programm“- Schreiben Sie
total_area(shapes)undlargest_shape(shapes). Beide Funktionen kennen ausschließlich den VertragShape; keinisinstance, keine Klassennamen. - Demonstrieren Sie beide mit einer gemischten Liste aus mindestens fünf Formen.
- Der Erweiterbarkeits-Beweis: Ergänzen Sie jetzt eine Klasse
RegularHexagon(side)(regelmäßiges Sechseck; Formeln recherchieren). Dabei gilt die Sperrklausel: Ausschließlich neue Zeilen sind erlaubt, keine bestehende Zeile darf sich ändern. Funktionierentotal_areaundlargest_shapesofort? Protokollieren Sie das Ergebnis als Kommentar; es ist der Kern der Abgabe.
Teil D - Expertenteil: Quadrat gegen Rechteck
Abschnitt betitelt „Teil D - Expertenteil: Quadrat gegen Rechteck“Die naheliegende Idee Square(Rectangle) ist das Lehrbuchbeispiel für eine problematische Vererbung. Untersuchen Sie sie selbst:
- Implementieren Sie
Squareeinmal als Subklasse vonRectangle(Konstruktor reichtsidezweimal weiter) und einmal als direkte Subklasse vonShape. Beide Varianten müssen den Vertrag erfüllen. - Ergänzen Sie in
Rectangleeine Methodescale_width(factor), die nur die Breite ändert. Was sollSquaredamit tun? Spielen Sie die Möglichkeiten durch (Breite ändern und kein Quadrat mehr sein; beide Seiten ändern und den Aufrufer überraschen; die Methode verweigern) und zeigen Sie an einem kurzen Codebeispiel, wie jede Variante berechtigte Erwartungen verletzt. - Fällen Sie Ihr Urteil in vier bis sechs Sätzen entlang des Substitutionsprinzips: Unter welcher Bedingung ist
Square(Rectangle)vertretbar (Stichwort: unveränderliche Objekte), und wann ist die Variante neben dem Rechteck die ehrlichere? - Zeichnen Sie das Klassendiagramm Ihrer endgültigen Hierarchie: abstrakte Klasse und Methoden gekennzeichnet, Vererbungspfeile korrekt.
Wissenscheck
Abschnitt betitelt „Wissenscheck“- Was erzwingt
@abstractmethod, und zu welchem Zeitpunkt schlägt eine unvollständige Subklasse fehl? - Warum darf
describe()in der abstrakten Klasse konkret sein, obwohlarea()abstrakt ist? - Woran erkennen Sie, dass
total_areagegen den Vertrag und nicht gegen konkrete Klassen programmiert ist? - Formulieren Sie das Open-Closed-Prinzip in einem Satz und nennen Sie die Stelle dieser Übung, die es belegt.
- Warum ist “jedes Quadrat ist ein Rechteck” mathematisch wahr, als Klassenbeziehung aber heikel?
shapes.py mit Vertrag, Implementierungen, polymorphen Funktionen und dem dokumentierten Erweiterbarkeits-Beweis; für Teil D beide Square-Varianten, das Urteil und das Diagramm.