Zur Hauptnavigation springen [Alt]+[0] Zum Seiteninhalt springen [Alt]+[1]

Möglicher Unterrichtsgang

Im Folgenden werden eine mögliche Abfolge der Themen skizziert und Beispielaufgaben vorgestellt. Es werden weder Vorgaben zum Zeitrahmen gemacht noch der Anspruch auf Vollständigkeit erhoben. Die vorgestellten Ideen sollen als Ausgangsbasis für den eigenen Unterricht dienen.

1. Kennenlernen des Projekts, Begriffsklärungen zu Typisierung/Typumwandlung

Im Projekt sind einige Stellen nur grob oder nicht fertig implementiert und können ausgebaut/verbessert werden. Diese sind im Code jeweils mit TODO: gekennzeichnet und es wird im Kommentar beschrieben was getan werden soll. Folgende Aufgaben können genutzt werden, um das Projekt kennen zu lernen.

Filmsammlung.java: TODO: Bounds Check , TODO: Korrekte Filmanzahl und TODO: Suche Serienepisode.java: TODO: Getter

Also nächstes kann es sinnvoll sein Typisierung und Typumwandlungen zu wiederholen. Hierbei sollte insbesondere einschränkende und erweiternde Typumwandlungen von einander unterschieden und der Begriff Typinferenz erklärt werden. Im Hintergrund-Dokument ist eine Erklärung mit Beispielen beschrieben, wie sie auch im Unterricht eingesetzt werden könnte.

Hilfreich ist es, die Fachbegriffe Typ, formale Werteparameter und konkrete Argumente im Kontext von Methoden einzuführen. Sollen Lambdaausdrücke nicht behandelt werden, kann dies auch weggelassen werden.

2. Generische Datentypen – Notwendigkeit, Deklaration

Als Hauptmotivation für generische Datentypen sollten folgende zwei Aspekte für die Schülerinnen und Schüler greifbar werden:

  • Typsicherheit wo immer möglich: Es ist besser, einen Fehler bei der Compilierung zu entdecken, als erst zur Laufzeit. Insbesondere gilt das für die Schule, da Ausnahmebehandlung dort kein Thema ist.
  • Redundanzen durch Abstraktion vermeiden: Um Typsicherheit zu erreichen, muss mehrfach Code geschrieben werden, der sich nur an wenigen Stellen vom bisherigen Code unterscheidet. Dies ist unerwünscht.

Folgende Aufgaben können für die Motivation gestellt werden:

  1. Siehe Programmierauftrag „Aufgabe.a1“ im Code.

    Siehe Lösungsordner

  2. Gib an, welche Arten Typumwandlungen stattfinden.

    /*

    * Falls fs eine Filmsammlung von Serien:

    * fs.get(0).getTitel(); //implitzite erweiternde Typumwandlung: Serie -> Film

    * ( (Serie) fs.getFilm(0) ).getAnzahlEpisoden(); //explizite einschränkende Typumwandlung: Film -> Serie

    *

    * Falls fs eine Filmsammlung von Kinofilmen:

    * Exception: java.lang.ClassCastException (class Kinofilm cannot be cast to class Serie)

    */

  3. Erkläre, weshalb es beim Aufruf von Aufgabe.a1(..) mit einer Sammlung von Kinofilmen zu einer Ausnahme kommt.

    Der Referenztyp Kinofilm steht in keiner direkten Beziehung zum Typ Serie und kann daher weder implizit noch explizit in den Zieltyp Serie umgewandelt werden.

  4. Mache Vorschläge, wie sicher gestellt werden, könnte dass es nicht zu der Ausnahme kommt und bewerte diese.

    Für die Sammlung von Serienobjekten kann eine eigene Klassen Seriensammlung geschrieben werden. Allerdings entstehen dabei viele Redundanzen, der Code unterscheidet sich nur im Typ der hinterlegten Reihung und der Wertparameter und Rückgabewerte in der Klasse.

Es folgt eine kurze Erklärung zur Deklaration generischer Typen (siehe Hintergrunddokument). Für die Kursteilnehmer ist es nur wichtig, den Code lesen zu können und die Fachbegriffe zu generischen Typen zuordnen zu können. Der Bildungsplan sieht nicht vor, dass generische Typen selbst deklariert werden.

Gegebenenfalls kann die generische Filmsammlung mit den SuS gemeinsam implementiert werden (die Klasse muss dann aus dem Projekt gelöscht und einzelne Aufgaben, die zu der Klasse in Beziehung stehen evtl. zunächst auskommentiert werden) oder die gegebene Implementierung analysiert werden. Folgende Aufgabe kann davor oder danach gestellt werden.

Öffne die Java-Dokumentation zu ArrayList einem generischen Datentyp. https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/ArrayList.html

  1. Untersuche die Methodenzusammenfassung und finde Methoden, welche für FilmsammlungGeneric<E> benötigt werden.

    Die Konstruktoren, add(E e), add(int index, E element), remove(int index), get(int index)

  2. Nenne die Methoden, die überschrieben und die zusätzlich implementiert werden müssen.

    Ein Konstruktor der eine Reihung als Argument nimmt, find(String titel), anzahlFilme, getBewertung()

  3. Optional: Implementiere FilmsammlungGeneric<E>

    Anmerkung: noch ohne upper Bound für den formalen Typparameter. Im Projekt sind die Zeilen mit Bound auskommentiert.

3. Generische Datentypen – Nutzung, Bounds

Die Syntax zur Nutzung kann mit den Beispielen aus dem Hintergrunddokument vorgestellt werden. Der Diamant-Operator wird eingeführt und erklärt (Typinferenz). Die Fachbegriffe müssen eingeführt werden. Die Fachbegriffe können leicht geprüft werden: Hierzu in einem Beispielcode Stellen markieren und nach dem Begriff fragen. Mögliche zusätzliche Aufgaben/Fragen könnten lauten:

  1. Erkläre, weshalb bei ArrayList<Integer> l3 = new ArrayList(); ein Laufzeitfehler möglich ist.

    Der Diamant-Operator fehlt. Demnach wird l3 der Originaltyp zugewiesen. Das Verhalten ist identisch zu dem bisherigen nicht parametrisierten Verhalten.

  2. Erkläre, weshalb bei ArrayList l4 = new ArrayList<Integer>(); ein Laufzeitfehler möglich ist.

    Der Zieltyp ist nicht parametrisiert. Das Verhalten ist identisch zu dem bisherigen nicht parametrisierten Verhalten.

  3. Siehe Programmierauftrag „Aufgabe.a2“: im Code.

    Siehe Lösungsordner

  4. Gib an, welche Arten Typumwandlungen statt finden, vergleiche mit Aufgabe.a1

    /*

    * fsG.get(1).getTitel(); //keine Typumwandlung, die von der Vaterklasse geerbte Methode wird aufgerufen.

    * fsG.get(1).getAnzahlEpisoden(); //keine Typumwandlung notwendig, weder implizit noch explizit

    */

  5. Serie.java: TODO: Typsicherheit garantieren

    ohne Lösung

  6. Für die folgende Aufgabe müssen Zeile 11 und der Block ab Zeile 71 kommentiert sein.

  7. Siehe Programmierauftrag „Aufgabe.a3“: im Code. Welche konkreten Typparameter sind erlaubt, welche nicht? [Anmerkung: Hier muss den SuS der Tipp gegeben werden, ihnen bereits bekannte andere als im Projekt definierte Typen als konkreten Typparameter zu verwenden.]

    Es sind alle Referenztypen erlaubt.

    Finde Beispiele für die es zu Compilierungs/Laufzeitfehlern kommen kann.

    Wähle z.B. String als konkreten Typparameter: Compilierungsfehler: cannot find symbol ...

  8. Alternative zu Aufgabe 6 mit kommentierter Zeile 10 und nicht kommentierter Zeile 11 und dem Block ab Zeile 71

  9. Erkläre weshalb es in Zeile 87 (sum += e.getBewertung();) zu einem Compilierungsfehler kommt.

    Die Variable e ist vom formalen Typ E. Der konkrete Typ ist zu Compilierungszeit nicht bekannt und könnte jeder denkliche konkrete Typparameter sein. Nicht jeder Typ implementiert die Methode getBewertung()

Es können nun Bounds eingeführt werden und der Code entsprechend angepasst werden. (Statt <E> : <E extends Film>) Die SuS könnten anschließend nochmals in „Aufgabe.a3“ im Code experimentieren und dadurch erkennen, dass es nicht mehr zu Compilierungsfehlern kommt.

4. Interfaces, Iterable – Arbeit mit der Dokumentation

Falls nicht bereits im Unterricht geschehen, sollten nun Interfaces eingeführt werden, denn diese begegnen dem Leser der Java-Dokumentation immer wieder. Der Abschnitt im Hintergrunddokument kann auch für den Unterricht verwendet werden. Die Schülerinnen und Schüler müssen jedoch keine Interfaces definieren oder implementieren.

Anschließend soll anhand des Interfaces Iterable die Arbeit mit der Dokumentation demonstriert werden.

Gestartet wird auf der Startseite der „Java® Platform, Standard Edition & Java Development Kit Version 11 API Specification“

Die Version 11 hat den Vorteil, dass es im Gegensatz zur Version 8 ein Suchfeld gibt: https://docs.oracle.com/en/java/javase/11/docs/api/index.html .

Aufgaben zur gemeinsamen Bearbeitung im Unterricht:

Öffne die Java-Dokumentation: https://docs.oracle.com/en/java/javase/11/docs/api/index.html und führe folgende Schritte durch. Notiere dir jeweils dir unklare Begriffe.

  1. Ein wichtige Schnittstelle ist das Iterable-Interface. Gib in der Suchmaske „Iterable“ ein und wähle java.util.Iterable aus. Welche Methoden definiert das Interface? Für was könnte das Interface dienen?
  2. Finde heraus was ein Iterator ist. Tipp lies die Dokumentation zu Iterator<T>.

Diese Aufgaben müssen zu keiner Lösung führen, sie dienen als Gesprächsgrundlage für den nächsten Unterrichtsschritt

5. Das Collections Framework und Iteration

Mit Hilfe der Dokumentation wird das Collections Framework erkundet. Es folgt eine Auswahl an Aufgaben, die hierzu gestellt werden können.

  1. Gib im Suchfeld „java.util“ ein und wähle die Dokumentation zum Paket java.util. Wähle im „Interface Summary“ das Interface Collection<E>. Betrachte die Methoden, die das Interface definiert. Fasse in wenigen Sätzen den Zweck zusammen, zu dem Klassen, die das Interface implementieren, genutzt werden können.

    Zur Sammlung gleichartiger Objekte.

  2. Gegeben sind die folgenden Interfaces und Klassen: <eigene Auswahl einsetzen>. Versuche mit Hilfe der Dokumentation eine Vererbungshierarchie als Klassendiagramm darzustellen.

    Folgendes Klassendiagramm beschreibt eine Maximalauswahl und sollte für den Unterricht auf ein Teildiagramm reduziert werden.

    Programmierparadigmen

    Klassendiagramm ZPG Informatik [CC BY-SA 4.0 DE], aus 03_unterrichtsverlauf.odt, bearbeitet

  3. In Kollaboration (Gruppenpuzzle, Museumsrundgang,…): Nutze die Dokumentation und beschreibe die Funkion (Aufbau und Einsatzzweck) einer der Klassen des Collections Framwork.
  4. Nenne das Interface, das beinahe alle Klassen des Collection-Framworks implementieren müssen.

    Iterable<E>

  5. Im Unterricht kann nun nochmal auf Iterable<E> und Iterator<T> eingegangen werden und kurz geklärt werden, welchen Zweck die Methoden hasNext() und next() erfüllen. Der Abschnitt im Hintergrunddokument ist hier auch für den Unterricht geeignet.

    Zur Übung reicht die Iteration mit einer while-Schleife und der erweiterten for-Schleife.

  6. Siehe Programmierauftrag „Aufgabe.a4“: im Code.

    An dieser Stelle muss auf die Vererbung bei generischen Typen eingegangen werden. FilmsammlungGeneric<Serie> erweitert nicht FilmsammlungGeneric<Film>, obwohl der Typ Serie den Typ Film erweitert. (siehe auch Hintergrunddokument)

    Für die SuS gibt es zunächst nur die Möglichkeit, mehrere Methoden zu schreiben. Im Lösungsordner findet sich eine Variante mit generisch deklarierter Methode. Dies kann versierten SuS gezeigt werden.

  7. Siehe Programmierauftrag „Aufgabe.a5“: im Code.

    siehe Lösungsordner

  8. Um die Nutzung von Collections und Iteration üben und prüfen zu können, ist es sinnvoll Aufgaben folgender Art zu stellen: Die Schülerinnen und Schüler erhalten eine kurze Spezifikation eines Problems in Form einer Beschreibung und eine zu nutzende Collection aus dem Collection-Framework. Als vorgegebene Collection kann eine konkrete Implementierung (z.B. ArrayList) gegeben sein, dann ist eine Deklaration/Initialisierung möglich. Es kann aber auch ein Interface vorgegeben werden, dann ist nur eine Iteration möglich.

  9. Beispiel für eine solche Aufgabe:

    Spezifikation: Eine Youtuberin erstellt regelmäßig Reiseberichte auf ihrem Kanal.

    Auf ihrer Webseite möchte sie die Namen alle Länder die sie bereits bereist hat ausgeben.

    Hierfür möchte sie immer wenn sie in einem Land war, dieses einer Sammlung hinzufügen.

    Es kann sein, dass sie ein Land mehrmals bereist. Um sich nicht merken zu müssen, ob sie bereits in diesem Land war, fügt sie es einfach nochmals ihrer Sammlung hinzu.

    Ist ein Land bereits in ihrer Reiseliste enthalten, wird es nicht erneut angefügt. Die Reihenfolge der bereisten Länder spielt keine Rolle.

    Eine Beispiel Eingabefolge könnte lauten: Deutschland, Indien, USA, Deutschland, Österreich, Süd-Afrika, Frankreich, USA

    Eine Ausgabe könnte dann folgendermaßen aussehen: "Indien, Deutschland, USA, Süd-Afrika, Österreich, Frankreich, "

    Collection: HashSet (https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/HashSet.html)

    Musterlösung:

    //Deklaration und Initialisierung
    HashSet<String> coll = new HashSet<>();
    coll.add("Deutschland");
    coll.add("Indien");
    coll.add("USA");
    coll.add("Deutschland");
    coll.add("Österreich");
    coll.add("Süd-Afrika");
    coll.add("Frankreich");
    coll.add("USA");
    // Ausgabe aller im HashSet gespeicherten Werte,
    // Duplikate gibt es nicht,
    // die Einfüge-Reihenfolge wird nicht notwendigerweise eingehalten.
    Iterator<String> it = coll.iterator();
    while( it.hasNext() ) {
        String land = it.next();
        System.out.print(land + ", ");
    }
    

 

Unterrichtsverlauf: Herunterladen [odt][216 KB]

 

Weiter zu Optional