Lehrplanbezug
Die Doppelstunde lässt sich dem Themenfeld der „Objektorientierte Modellierung / Programmierung“ für die Oberstufe einordnen. Insbesondere können die Schülerinnen und Schüler nach der Doppelstunde:
- einzelne Klassen sowie deren Vererbungsstrukturen in einer üblichen UML-Notation darstellen
- die Notwendigkeit/Möglichkeit der Spezialisierung bzw. der Erstellung eines einheitlichen Obertyps und entwerfen entsprechende Vererbungshierarchien
- polymorphe Methoden implementieren, in dem sie Methoden einer Oberklasse überschreiben und dadurch spezialisieren
Zusatzinformation
In den nachfolgenden Implementierungen wird bewusst auf die Begriffe „Setter“ und „Getter“ bzw. „set“ und „get“ verzichtet, weil die Schülerinnen und Schüler das Geheimnisprinzip nicht kennen. Deshalb wurde eine möglichst sinnvolle Benennung der Methodennamen gewählt und die Begriffe „setter“ sowie „getter“ bewusst nicht erwähnt.
Verlaufsplanung


Vorwissen zu OOP aktivieren

Zunächst wird das Vorwissen zu objektorientierte Programmierung aktiviert, indem die Schülerinnen und Schüler alles, was ihnen zu dem Begriff „objektorientierte Programmierung (OOP)“ einfällt, nennen sowie beschreiben. Dabei sollen Begriffe wie Klasse, Objekt, Methode, Attribut, Konstruktor genannt werden.
Danach wird eine Implementierung einer Klasse „Auto“ an die Tafel projiziert und die Schülerinnen und Schüler sollen die Begriffe wie Konstruktor, Attribut und Methode zuordnen. Anhand der Implementierung soll die Klasse auch ein Klassendiagramm sowie ein Objektdiagramm angeben.
Die Implementierung der Klasse „Auto“ ist folgende:
class Auto():
def __init__(self, marke, baujahr):
self.marke = marke
self.baujahr = baujahr
def starten(self):
print(self.marke + " startet")
def bekommeMarke(self):
print(self.marke)
def bekommeBaujahr(self):
print(self.baujahr)
def setzeBaujahr(self, bj):
self.baujahr = bj
Einstieg in Vererbung

Zum Einstieg in Vererbung werden zunächst verschiedene Fahrzeuge sowie deren Klassendiagramme an die Tafel projiziert mit der Frage „Was passiert, wenn wir ein Fahrzeugverleihsystem mit Motorrad, PKW, LKW und Fahrrad programmieren wollen?“. Dabei möchte man diese Fahrzeuge in ein Fahrzeugverleihsystem implementieren. Ziel des Einstiegs ist es, dass den Schülerinnen und Schüler auffällt, dass viele Attribute und Methoden ähnlich sind und man deshalb sehr oft das gleiche programmieren müsste. Deshalb ist das Konzept der Vererbung hilfreich und wird wie folgt in einem Klassendiagramm dargestellt:

Erarbeitung Vererbung
H5P-Modul zur Erarbeitung von Vererbung:
Die Erarbeitung des Themas Vererbung erfolgt anschließend in dem d H5P Modul „Vererbung“. Hierbei wird aufgegriffen, dass verschiedene Klassendiagramme die gleichen bzw. die selben Attribute sowie Methoden haben können, wodurch sich bestimmte Aspekte bei der Implementierung wiederholen würden. Um doppelten Code zu vermeiden, wird das Konzept der Vererbung bei der objektorientierten Programmierung erklärt. Dabei können Methoden der Superklasse überschrieben werden, falls sie speziellere Anforderungen innerhalb der Subklasse haben.
Vererbung implementieren
H5P-Modul zu Vererbung implementieren:
An die allgemeine Erarbeitung von Vererbung schließt sich das H5P Modul „Vererbung implementieren“ an, in dem die Schülerinnen und Schüler lernen, wie man in Python Vererbung programmiert. Dabei werden die verschiedene Klassendiagramme sowie die Klassenhierarchie der Problemstellung wieder aufgegriffen. Vor der Erarbeitung der Implementation von Vererbung steht eine kleine Lernerfolgskontrolle an, bei der die Schülerinnen und Schüler angegebene Begriffe in die richtigen Lücken schreiben sollen. Dadurch soll sichergestellt werden, dass sie die Begriffe verstanden haben. Danach erfolgt zunächst die Darstellung bei der Superklasse, die wie jede andere Klasse implementiert wird. Bei den Subklassen dagegen ändern sich folgende zwei Aspekte:
- in den Klammer der Klassendeklaration steht der Klassenname der Superklasse
- der Konstruktor der Subklasse erhält neben seinen Parametern noch die der Superklasse und schreibt diese in seinen Konstruktor mit dem Aufruf
super().__init__(parameter1, parameter2, …).
Danach werden die Parameter der Subklasse deklariert.
Nach der Darstellung der Implementierung von Vererbung anhand der Problemstellung, wird die allgemeine Darstellung von Vererbung dargestellt. Dies sieht wie folgt aus:
class B(object):
def __init__(self, parameterB):
self.attributOberklasse = parameterB
#hier können noch weitere Attribute der Oberklasse folgen
def bekommeAttrOberkl(self):
print(self.attributOberklasse)
def setzeAttrOberkl(self, parameter):
self.attributOberklasse = parameter
class A(B):
def __init__(self, parameterB):
super().__init__(parameterB)
self.attributUnterklasse = None
#hier können noch weitere Attribute der Unterklasse folgen
#attributOberklasse automatisch geerbt und kann von Objekt
#der Klasse A verwendet werden
def bekommeAttrUnterkl(self):
print(self.attributUnterklasse)
def setzeAttrUnterkl(self, parameter):
self.attributUnterklasse = parameter
#Methoden bekommeAttrOberkl und setzeAttrOberkl werden automatisch
#geerbt von B und können dadurch von einem Objekt der Klasse A auf
#dieses angewendet werden
Implementierung Vererbung
Die Schülerinnen und Schüler erhalten nach der Erarbeitung, wie man Vererbung in Python implementiert, eine Referenzimplementierung. Diese sollen sie zunächst nachvollziehen, in dem sie den Code lesen und Objekte erzeugen, um die Methoden zu testen. Danach werden die fehlenden Klassen anhand der Klassenhierarchie implementiert. Nun testen die Schülerinnen und Schüler ihre Implementierung. Dabei können sie sich am Testprogramm orientieren. Schnelle Schülerinnen und Schüler können dann noch weitere Fahrzeuge in das Fahrzeugverleihsystem einfügen oder zusätzliche Attribute sowie Methoden implementieren.
Die Referenzimplementierung ist folgende:
class Fahrzeug():
def __init__(self, lg, zGG, aR):
self.leergewicht = lg
self.zulGesamtGew = zGG
self.anzahlRaeder = aR
self.verfuegbar = False
def setzeVerfuegbarkeit(self, status):
self.verfuegbar = status
def bekommeVerfuegbarkeit(self):
print(self.verfuegbar)
class KFZ(Fahrzeug):
def __init__(self, lg, zGG, aR, hG, l, f):
super().__init__(lg, zGG, aR)
self. hoechstGeschw = hG
self.leistung = l
self.fahrerlaubnis = f
def pruefeFahrerlaubnis(self):
print(self.fahrerlaubnis)
def bekommeVerfuegbarkeit(self):
super().bekommeVerfuegbarkeit()
class PKW(KFZ):
def __init__(self, lg, zGG, aR, hG, l, f, aSP):
super().__init__(lg, zGG, aR, hG, l, f)
self.anzahlSitzPlaetze = aSP
def pruefeFahrerlaubnis(self):
super().pruefeFahrerlaubnis()
# ------------------------------------------------------
# Testprogramm
# Erstelle einen PKW
pkw = PKW(lg=1300, zGG=1800, aR=4, hG=210, l=110, f="B", aSP=5)
#man kann Parameter benennen, dies ist aber kein muss
print("PKW:")
print(f"Anzahl Sitzplätze: {pkw.anzahlSitzPlaetze}")
pkw.pruefeFahrerlaubnis()
pkw.setzeVerfuegbarkeit(True)
pkw.bekommeVerfuegbarkeit()
print()
Eine mögliche, in Bezug zum Klassendiagramm vollständige Implementierung, könnte wie folgt aussehen:
class Fahrzeug():
def __init__(self, lg, zGG, aR):
self.leergewicht = lg
self.zulGesamtGew = zGG
self.anzahlRaeder = aR
self.verfuegbar = False
def setzeVerfuegbarkeit(self, status):
self.verfuegbar = status
def bekommeVerfuegbarkeit(self):
print(self.verfuegbar)
class KFZ(Fahrzeug):
def __init__(self, lg, zGG, aR, hG, l, f):
super().__init__(lg, zGG, aR)
self. hoechstGeschw = hG
self.leistung = l
self.fahrerlaubnis = f
def pruefeFahrerlaubnis(self):
print(self.fahrerlaubnis)
def bekommeVerfuegbarkeit(self):
super().bekommeVerfuegbarkeit()
class Fahrrad(Fahrzeug):
def __init__(self, lg, zGG, aR, rH):
super().__init__(lg, zGG, aR)
self.rahmenHöhe = rH
def bekommeRahmenHöhe(self):
print(self.rahmenHöhe)
def bekommeVerfuegbarkeit(self):
super().bekommeVerfuegbarkeit()
class Motorrad(KFZ):
def __init__(self, lg, zGG, aR, hG, l, f):
super().__init__(lg, zGG, aR, hG, l, f)
def pruefeFahrerlaubnis(self):
super().pruefeFahrerlaubnis()
class PKW(KFZ):
def __init__(self, lg, zGG, aR, hG, l, f, aSP):
super().__init__(lg, zGG, aR, hG, l, f)
self.anzahlSitzPlaetze = aSP
def pruefeFahrerlaubnis(self):
super().pruefeFahrerlaubnis()
class LKW(KFZ):
def __init__(self, lg, zGG, aR, hG, l, f, nl):
super().__init__(lg, zGG, aR, hG, l, f)
self.nutzlast = nl
def pruefeFahrerlaubnis(self):
super().pruefeFahrerlaubnis()
# ------------------------------------------------------
# Testprogramm
# Erstelle ein Fahrrad
fahrrad = Fahrrad(10, 120, 2, 55)
print("Fahrrad:")
fahrrad.bekommeRahmenHöhe()
fahrrad.setzeVerfuegbarkeit(True)
fahrrad.bekommeVerfuegbarkeit()
print()
# Erstelle ein Motorrad
motorrad = Motorrad(200, 350, 2, 180, 100, "A")
print("Motorrad:")
motorrad.pruefeFahrerlaubnis()
motorrad.bekommeVerfuegbarkeit()
motorrad.setzeVerfuegbarkeit(True)
motorrad.bekommeVerfuegbarkeit()
print()
# Erstelle einen PKW
pkw = PKW(1300, 1800, 4, 210, 110, "B", 5)
print("PKW:")
print(f"Anzahl Sitzplätze: {pkw.anzahlSitzPlaetze}")
pkw.pruefeFahrerlaubnis()
pkw.setzeVerfuegbarkeit(True)
pkw.bekommeVerfuegbarkeit()
print()
# Erstelle einen LKW
lkw = LKW(5000, 12000, 6, 120, 300, "C", 8000)
print("LKW:")
print(f"Nutzlast: {lkw.nutzlast} kg")
lkw.pruefeFahrerlaubnis()
lkw.bekommeVerfuegbarkeit()
lkw.setzeVerfuegbarkeit(False)
lkw.bekommeVerfuegbarkeit()
Abschluss
H5P-Modul zum Abschluss mit Quiz über Vererbung/OOP:
Als Abschluss der Unterrichtsstunde ist ein Quiz über das Thema Vererbung im Themenfeld der objektorientierten Programmierung OOP geplant. Dabei werden verschiedene wichtige Begriffe, wie Superklasse oder Subklasse, abgefragt als auch allgemeine Fragen zu sowohl OOP als auch Vererbung gestellt. Hierbei wird das Tool „Single Choice Set“ sowie „True/False Question“ verwendet. Die letzte Frage bezieht sich auf die Ausgabe einer kleinen Implementierung, bei der das Prinzip der Vererbung angewendet ist.
Unterrichtsverlauf
Der Unterricht fand in der 7. und 8. Stunde statt. In der Klasse waren 9 Lernende. Der Klassenraum war mit einem Smartboard ausgestattet, wodurch eine Projektion des Tablets möglich wurde. Die Schüler besaßen Zugriff auf einen eigenen Schulrechner, auf dem sie programmieren sowie die H5P Module bearbeiten können.
Während des Unterrichts wurde folgende Datei als Tafelanschrift verwendet, wodurch die Klasse den aktuellen Stand sowie eine Visualisierung sehen konnten (die handgeschriebenen Wörter wurden in der Stunde gemeinsam mit der Klasse behandelt, für weitere Information siehe Text unten):


Die Unterrichtsstunde begann mit der Begrüßung der Klasse. Nach der Begrüßung sollten die Schülerinnen und Schüler ihre Computer vorab hochfahren, damit sie später direkt an ihrem PC arbeiten können. Dies gewährleistet einen flüssigeren Unterricht.
Die anschließenden Wiederholung fand in einem Sitzkreis statt. Dabei sollten die Schülerinnen und Schüler verschiedene Begriffe zum Thema „Objektorientierte Programmierung (OOP)“, wie Klasse, Attribut, Methode oder Konstruktor, nennen, die dann an der Tafel in Form einer Sammlung von Wörtern aufgeschrieben wurden (siehe oben). Diese Phase war offen gehalten und nur die grundlegenden Begriffe wurden wiederholt und erklärt. Daran schloss sich auch eine Wiederholung des Themas anhand eines Codebeispiels (siehe oben). Hierbei sollten die Schülerinnen und Schüler die zuvor wiederholten Begriffe im Code zuordnen. Anhand der Implementierung wurden auch das Klassendiagramm sowie ein Objektdiagramm erstellt. Dabei soll ich eine Schülerin übergangen, die bereits alles wichtige nannte. Dies habe ich im Unterricht leider nicht wahrgenommen. Die Wiederholung des Themas „objektorientierte Programmierung“ dauerte etwa 20 Minuten, dies war auch so geplant (siehe Verlaufsplanung). Die Klasse konnte auch alle grundlegenden Begriffe der objektorientierten Programmierung nennen sowie erklären.
Daran schloss sich der Einstieg in das neue Thema „Vererbung“. Hierbei sollten die Schülerinnen und Schüler sich vorstellen, sie würden in einem Fahrzeugverleihsystem arbeiten und verschiedene Fahrzeuge sollen implementiert werden. Zunächst wurde ein Bild von verschiedenen Fahrzeugen gezeigt, bevor die zugehörigen Klassendiagrammen angesprochen wurden (siehe oben). Dabei sollten die Schülerinnen und Schüler auf Gemeinsamkeiten sowie Unterschiede achten. Hierbei wurde zuerst die bislang unbekannte (+/-) Notation der objektorientierten Programmierung von einem Schüler genannt. Da dies in unserem Kontext keine Relevanz hatte, konnte die Frage schnell geklärt werden. Darüber hinaus tat sich die Klasse etwas schwer auf Gemeinsamkeiten innerhalb der Klassen kommen, da sie die Menge der Attribute bzw. der Methoden trotz gleicher Benennung als verschieden sahen. Jedoch wurde dann festgestellt, dass die Bedeutung der Attribute innerhalb den verschiedenen Klassendiagrammen dieselbe ist. Dadurch wurde einzelne Attribute von den Schülerinnen und Schüler unterschieden. Außerdem konnte die Klasse nachvollziehen, dass eine Implementierung, bei der alle Klassen einzeln implementiert werden, einen hohen Aufwand mit sich zieht, da man die meisten Attribute und Methoden mehrfach schreiben muss. Eine Schülerin hat eine imperative Herangehensweise über „if/else statements“ zur Unterscheidung vorgeschlagen, ob ein Attribut in eine Klasse gehört oder nicht. Dabei wird abgefragt, welches Fahrzeug man hat und je nachdem werden die entsprechenden Attribute zugeordnet. Dies ist ein sehr interessanter Gedankengang, bei dem man allerdings vieles mehr beachten müsste. Dieser Moment eignete sich für die Überleitung zum Thema der Stunde „Vererbung“, um unter anderem doppelten Code zu vermeiden. Dadurch wurde der Vorteil bzw. die Notwendigkeit von Vererbung hergeleitet. Im Anschluss daran wurde gezeigt, wie das Klassendiagramm mit dem neuen Fachkonzept in einem gemeinsamen Klassendiagramm aussieht. Im Anschluss daran wurden die Schülerinnen und Schüler an die beiden H5P-Module (vergleiche Abschnitt „Erarbeitung Vererbung“ sowie „Vererbung implementieren“) über Vererbung geschickt. Die Klasse war mit der Bearbeitung der H5P-Modulen mit dem Pausengong fertig, wodurch die Besprechung nach der Pause stattfand. Bei der Besprechung wurde nochmal auf die neuen Begriffe wiederholt und auf das Vorgehen beim Implementieren hingewiesen. Dadurch konnte auf die Übungsphase mit der Aufgabe der Implementierung übergeleitet werden.
Die Lernenden sollten sich in der Übungsphase mit der bereitgestellten Implementierung zum Fahrzeugverleihsystem vertraut machen (vergleiche Referenzimplementierung unter „Vererbung implementieren“) und die fehlenden sowie neu ausgedachten Klassen/Attribute/Methoden implementieren. Die Schülerinnen und Schüler zeigten dabei viel Interesse und diskutierten untereinander, welche neuen sinnvolle Attribute sie einfügen könnten. Da die Klasse nur 9 Lernende umfasste, konnte ich mir während der Übung von jeder Schülerin und von jedem Schüler einen Überblick verschaffen, was sie programmieren und wie gut das läuft. Dadurch ließ ich die geplante Phase der Präsentation weg, wodurch die Klasse mehr Zeit bekam zum Programmieren.
Das Quiz zum Thema „Vererbung“, bei dem die Schülerinnen und Schüler Fragen zum neu gelernten Stoff beantworten sollten, bildete einen runden Abschluss der Unterrichtsstunde.
Insgesamt würde ich sagen, dass die Stunde gut und nach meinem Plan bzw. nach meiner Vorstellung verlief. Dies äußert sich darin, dass während der Bearbeitung der Aufgabenstellung und dem abschließenden Quiz der Lernzuwachs erkennbar und überprüfbar wurde. Durch die „lange“ Wiederholung zu Beginn der Stunde wurden alle Schülerinnen und Schüler auf ihrem aktuellen Stand abgeholt, wodurch das neu gelernte schnell verstanden und umgesetzt werden konnte. Dadurch arbeiteten alle fleißig mit und zeigten großes Interesse beim Programmieren des Fahrzeugverleihsystems.
Die erneute Bestätigung, Lehrer zu werden, ist für mich die wichtigste Erkenntnis aus dem Unterricht. Dies zeigte sich vor allem in der positiven Lehrer-Schüler-Beziehung als auch am lernförderlichen Klima. Zudem hat mir die Arbeit mit den Schülern viel Freude bereitet und gezeigt, wie bereichernd es ist, Wissen zu vermitteln und individuelle Lernfortschritte zu begleiten. Besonders motivierend war es zu sehen, wie die Lernenden die neuen Inhalte aufnehmen, verstehen und schlussendlich anwenden können. Die Reflexion meines eigenen Unterrichts hat mir enorm geholfen, meine Rolle als Lehrkraft auszubauen und meine pädagogischen Fähigkeiten zu verbessern. Deshalb möchte ich in den kommenden, selbst gehaltenen Unterrichtsstunden die Kritikpunkte und das Feedback umsetzen, um eine Verbesserung des Unterrichts zu erreichen. Durch diese Anpassungen soll die Unterrichtsqualität gesteigert und meine Lehrerkompetenz weiterentwickelt werden.