Skip to main content

2024 | Buch

Java für Teetrinker

Ein funktionaler Zugang zur Programmierung mit Java

insite
SUCHEN

Über dieses Buch

Es ist an der Zeit Java didaktisch neu zu denken. Seit der ersten offiziellen Vorstellung von Java 1995 ist viel passiert. Ursprünglich war Java konsequent als eine rein objektorientierte Sprache definiert. Über die Jahre wurde die Sprache weiterentwickelt und ist alles andere als kalter Kaffee.

Lambda-Ausdrücke, Datenhaltungsklassen, Pattern-Matching oder Datenströme ermöglichen es, neben dem objektorientierten Programmierparadigma von Anfang an das funktionale Programmierparadigma in der Lehre anzuwenden.

Dieses Lehrbuch verfolgt konsequent den Weg, auch die aktuelleren Konstrukte von Java einzubeziehen und damit einen dem heutigen Stand der Technik passenden Kurs anzubieten, der allen wichtigen Programmierparadigmen gerecht wird und auf die Softwareentwicklung in unterschiedlichen Programmiersprachen vorbereitet.

Dabei werden die wichtigsten Datenstrukturen und Klassiker der Informatik als Beispiele verwendet. So begegnen uns Mengen in Form von Suchbäumen genauso wie durch Hashwerte organisiert. Es werden Klassiker wie der Chatbot „Eliza“ oder die Simulation „Game of Life“ implementiert. Die Alpha-Beta-Suche für den besten Spielzug eines Strategiespiels und kleine visuelle Spiele im zweidimensionalen Raum sind vertreten, wie die Generierung von Code für den Datenbank- und Web-Zugriff auf Objekte.

Zu guter Letzt wird für eine eigene kleine Programmiersprache Assembler-Code generiert. So entsteht ein Programmierkurs, der sich von Anfang an der Struktur und Interpretation von Programmen widmet.

Inhaltsverzeichnis

Frontmatter

Funktionale Programmierung

Frontmatter
Kapitel 1. Ausdrücke
Zusammenfassung
In diesem Kapitel geht es um Ausdrücke, die sich zu einem Ergebnis ausrechnen lassen. Ausdrücke können einfache arithmetische Berechnungen und Operatoren enthalten und kennen Fallunterscheidungen aufgrund von Werten. Die acht primitiven Typen in Java werden eingeführt. Funktionsdefinitionen, die in einem Ausdruck unter Verwendung der Funktionsargumente das Funktionsergebnis definieren, werden behandelt. In Ausdrücken können zuvor definierte Funktionen aufgerufen werden. Funktionen können rekursiv sein. Es werden unterschiedliche Formen der Rekursion gezeigt und die schrittweise manuelle Auswertung von Ausdrücken. Ergebnisse von Ausdrücken werden in Variablen gespeichert.
Sven Eric Panitz
Kapitel 2. Referenz Datentypen
Zusammenfassung
In diesem Kapitel werden einzelne Daten zu strukturierten Daten zusammengefasst. Auf diesen zusammengefassten Datenobjekten werden Funktionen in Form von Methoden definiert. Als allgemeinster Datentyp wird die Klasse Object eingeführt. Ausdrücke zur Unterscheidung von Daten über ihren Typ und zur Dekonstruktion der einzelnen Bestandteile werden vorgestellt. Schnittstellen werden zur Bildung von Summentypen aus mehreren unterschiedlichen strukturierten Datenklassem verwendet. Datenklassen werden mit Typvariablen generisch definiert. Datenklassen werden rekursiv definiert und als ausgiebiges Beispiel werden verkettete Listen behandelt. Als weitere Datentypen werden Aufzählungen eingeführt.
Sven Eric Panitz
Kapitel 3. Funktionsdaten
Zusammenfassung
Funktionen werden als Daten behandelt. Funktionstypen über funktionale Schnittstellen definiert und mit Lambda-Ausdrücken Funktionen erzeugt. Damit lässt sich Programmieren höherer Ordnung realisieren, indem Funktionen als Parameter Funktionsobjekte übergeben werden. Beispiele zur Messung der Ausführungszeit mit Hilfe von nullstelligen Funktionsobjekten werden gegeben und eine verzögert ausgewertete Datenstruktur entwickelt.
Sven Eric Panitz
Kapitel 4. Ein Klassiker: Psychotherapiesimulation Eliza
Zusammenfassung
Die zuvor eingeführten Konzepte werden genutzt, um das Programm Eliza, das eine Therapiesitzung simuliert, zu implementieren. Dabei werden die verketteten Listen für die Datenhaltung des Programms verwendet.
Sven Eric Panitz

Imperative Programmierung

Frontmatter
Kapitel 5. Anweisungen
Zusammenfassung
Anweisungen von der Zuweisung, über Fallunterscheidungen bis hin zu Schleifen werden eingeführt. Der Kontrollfluss eines Programms wird erläutert. Struktogramme und Flussdiagramme zur Illustration von Kontrollstrukturen werden gezeigt und der Kontrollfluss eines Programms erläutert. Vor Seiteneffekten in Funktionen wird gewarnt.
Sven Eric Panitz
Kapitel 6. Java als kompilierte Sprache
Zusammenfassung
Javaprgramme werden nicht direkt in der JShell interaktiv ausgeführt, sondern zu Maschinencode übersetzt und dieser mit der virtuellen ausgeführt. Hierzu benötigt die auszuführende Klasse eine Hauptmethode. Die Optionen zur Kompilierung werden gezeigt. Kompilierte Klassen können in JAR-Dateien verpackt werden. Der Klassenpfad ist entscheidend bei der Kompilierung und Ausführung von Klassen. Pakete sind ein wichtiges Merkmal, um Klassen zu gruppieren. Sichtbarkeiten helfen, Abstraktionsebenen einzuführen.
Sven Eric Panitz

Objektorientierte Programmierung

Frontmatter
Kapitel 7. Klassen für modifizierbare Objekte
Zusammenfassung
Anders als bei Datenklassen sind für allgemeine Klassen Konstruktoren und Felder separat zu definieren. Felder sind hier veränderbare Variablen, sodass sich Objekte modifizieren lassen. Das Hauptkonzept der Objektorientierung ist die Vererbung an Unterklassen und die späte Bindung bei Methodenaufrufen. Zusätzlich lassen sich Schnittstellen definieren, die durch Klassen implementiert werden können. Klassen und Schnittstellen können generisch über Inhaltstypen sein. Als Beispiel für generische Klassen modifizierbare Objekte werden weitere Implementierungen von Listen und Mengen gegeben.
Sven Eric Panitz
Kapitel 8. Ausnahmen
Zusammenfassung
Es gibt während des Ablaufs eines Programms Situationen, die als Ausnahmen zum eigentlichen Programmablauf betrachtet werden können. Java hält ein Konzept bereit, das die Behandlung von Ausnahmen abseits der eigentlichen Programmlogik erlaubt. Das Konzept des Werfens und Fangens von Objekten in Ausnahme- oder Fehlersituationen wird eingeführt. Die verschiedenen Klassen von zu werfenden Objekten werden unterschieden. In den Programmfluss wird bei Ausnahmesituationen eingegriffen. Ausnahmen, die nicht gefangen werden, sofern es keine Alltagsausnahmen sind, müssen für Methoden deklariert werden.
Sven Eric Panitz

Ausbaukonzepte

Frontmatter
Kapitel 9. Objekte für Schleifen
Zusammenfassung
Iteration mit Schleifen ist ein fundamentales Konzept der Programmierung. Wir zeigen, wie Schleifen in Objekte abstrahiert werden können. Iterierbare Objekte haben Iteratoren, die die Iteration für Elemente steuern. Die Verwendung einer für-alle Schleife wird für iterierbare Objekte ermöglicht. Eine weitere Abstraktion über Schleifen stellt die Faltungsfunktion dar. Um eine parallele Iteration zu ermöglichen, gibt es Stream-Objekte. Auch diese sind Abstraktionen der Iteration und in der Lage, die Iteration parallel durchzuführen.
Sven Eric Panitz
Kapitel 10. Eingabe und Ausgabe
Zusammenfassung
Kommunikation ist eine der wichtigsten Merkmale für die meiste Software, die wir benutzen. Kommunikation bedeutet für ein Programm, dass es Eingaben aus externen Datenquellen bekommt und Ausgaben tätigen kann. Das kann sich auf Tastatureingaben beziehen, auf Dateien im Dateisystem beziehen oder über ein Netzwerk geschehen. Javas Standard-API für Ein-/Ausgabeoperationen basiert auf Datenströmen. Für textbasierte Operationen werden Texte aus Datenströmen mit einem Encoding zwischen Binärdaten und Textdaten konvertiert. Spezialisierte Datenströme können serialisierbare Objekte lesen und schreiben.
Sven Eric Panitz
Kapitel 11. Grafische Benutzeroberflächen mit Swing
Zusammenfassung
Als Beispiel für die Programmierung graphischer Benutzeroberflächen wird die Swing Bibliothek vorgestellt. Grafische Objekte lassen sich ideal in der Objektorientierung modellieren. Ihre Anordnung wird durch Layoutmanager gesteuert. Ihre Interaktion basiert auf Events. Events können auch zeitgesteuert durch Timer-Objekte ausgelöst werden. Die Behandlung von einfachen Events lässt sich durch Lambda-Ausdrücke spezifizieren. Für komplexere Ereignisbehandlung können innere Klassen verwendet werden. Als kleines Beispiel findet sich die Programmierung von Fraktalen, den sogenannten Apfelmännchen.
Sven Eric Panitz
Kapitel 12. Metaprogrammierung
Zusammenfassung
In Java kann sowohl dynamisch während der Laufzeit allgemeiner Code für beliebige Klassen ausgeführt als auch statisch während der Kompilierung Code erzeugt werden. Dieses Kapitel behandelt, wie man in Java Bibliotheken und komplexe Frameworks umsetzen kann. Hierzu wenden wir zwei noch nicht verwendete Techniken an: das Java Reflection API und Annotationen. Ziel soll es sein, dass für Javaklassen dynamisch Code generiert wird, um Objekte in Datenbanken zu speichern. Für Annotationen wird ein Prozessor geschrieben, der statisch Code generiert, mit denen Objekte über einen Server zugegriffen werden können.
Sven Eric Panitz

Projekte

Frontmatter
Kapitel 13. Zweidimensionale Spieleanwendung
Zusammenfassung
In diesem Kapitel wird eine kleine Bibliothek zum Entwickeln von zweidimensionalen Spieleanwendungen entwickelt. Ein erstes kleines Spiel wird mit dieser Bibliothek gezeigt und schließlich eine Simulation für die Ausbreitung einer Infektionskrankheit implementiert.
Sven Eric Panitz
Kapitel 14. Strategiespiele
Zusammenfassung
In diesem Kapitel werden einfache klassische Strategiespiele umgesetzt. Es wird eine minimale grafische Anwenderschnittstelle geben, sowie einen allgemeinen Algorithmus für einen möglichst guten Zug, sodass man gegen den Computer spielen kann. Wir werden nicht nur ein konkretes Spiel umsetzen, sondern eine kleine Rahmenbibliothek erstellen, mit der weitere Spiele umgesetzt werden können. Wir setzen in diesem Kapitel nicht darauf, eine möglichst optimierte Version zu entwickeln, sondern eine möglichst allgemeingültige, die mit möglichst wenig Code auskommt. Wem insbesondere der Computer als Gegner zu langsam ist, kann ausgehend von unserer Lösung eine optimierte Lösung ableiten.
Sven Eric Panitz
Kapitel 15. Ein Kompilator
Zusammenfassung
In diesem Projekt wird ein Kompilator für eine kleine Programmiersprache entwickelt. Ein Kompilator ist ein Computerprogramm, das andere Programme als Eingabe erhält und wiederum Computerprogramme als Ausgabe erzeugt. Es gibt also bei einem Kompilator drei beteiligte Programmiersprachen. Die Quellsprache des Programms, das der Kompilator als Eingabe erhält. Die Zielsprache, in die das Eingabeprogramm übersetzt wird. Dies ist oft eine Maschinensprache in Form von Assembler. Die Implementierungssprache, in der der Kompilator entwickelt wurde. Für dieses Beispielprojekt nutzen wir als Implementierungssprache Java und als Quellsprache eine einfache Sprache mit Bedingungen, Schleifen und Funktionsaufrufen. Zielsprache ist Gnu Assembler (GAS) für x86-64-Architekturen.
Sven Eric Panitz
Kapitel 16. Die Zukunft von Java
Zusammenfassung
Es ist vermessen, die Zukunft vorherzusagen. In diesem abschließenden Kapitel sollen ein paar Merkmale, die Java derzeit nicht hat, aufgelistet werden. Es handelt sich um Merkmale, die in anderen Sprachen etabliert sind. Bei der derzeitigen agilen Weiterentwicklung von Java ist wahrscheinlich, dass einige davon irgendwann auch Einzug in die Sprache Java finden werden.
Sven Eric Panitz
Backmatter
Metadaten
Titel
Java für Teetrinker
verfasst von
Sven Eric Panitz
Copyright-Jahr
2024
Verlag
Springer Berlin Heidelberg
Electronic ISBN
978-3-662-69321-6
Print ISBN
978-3-662-69320-9
DOI
https://doi.org/10.1007/978-3-662-69321-6

Premium Partner