Objektorientierte Programmierung
Prozedurale vs. Objektorientierte Programmierung
Prozedurale Programmierung:
- Fokus auf Funktionen (Prozeduren), die nacheinander ausgeführt werden.
- Daten und Funktionen sind getrennt.
- Beispiel: JavaScript
Objektorientierte Programmierung (OOP):
- Fokus auf Objekte, die Daten (Attribute) und Funktionen (Methoden) kombinieren.
- Förderung von Wiederverwendbarkeit, Wartbarkeit und Erweiterbarkeit.
- Beispiel: Java
Prozedur und Funktion – Unterschied
- Funktion: Gibt einen Rückgabewert zurück.
- Prozedur: Führt eine Aufgabe aus, gibt aber keinen Wert zurück (in Java:
void
Methoden).
// Prozedur
void druckeBegrüßung() {
System.out.println("Hallo!");
}
// Funktion
int addiere(int a, int b) {
return a + b;
}
Exceptions
Exceptions sind Fehler, die während der Programmausführung (also zur Laufzeit) auftreten. Java bietet dafür ein System, um diese Fehler abzufangen und das Programm kontrolliert weiterlaufen zu lassen.
try
und catch
? Warum brauchen wir
Manche Fehler, wie eine Division durch 0, bringen das Programm zum Absturz – wenn du nichts unternimmst.
Stattdessen kannst du mit try
und catch
solche Fehler abfangen und eine passende Reaktion darauf geben, z. B. eine Fehlermeldung anzeigen.
try {
int ergebnis = 10 / 0; // Versuch: Division durch 0
} catch (ArithmeticException e) {
System.out.println("Fehler: Division durch 0");
}
Collections
Collections sind vorgefertigte Datenstrukturen, die verwendet werden, um Gruppen von Objekten zu speichern, zu verwalten und zu verarbeiten.
Die wichtigsten Interfaces sind:
List
Eine List
speichert Elemente in einer festen Reihenfolge (Index-basiert) und erlaubt Duplikate.
Beispiel:
List<String> namen = new ArrayList<>();
namen.add("Anna");
namen.add("Ben");
namen.add("Anna"); // erlaubt!
- Zugriff über
get(index)
- Wichtigste Implementierungen:
ArrayList
(schneller Zugriff, langsames Einfügen in der Mitte)LinkedList
(schneller beim Einfügen/Löschen in der Mitte)
Set
Ein Set
speichert keine doppelten Elemente – jedes Element ist einzigartig.
Beispiel:
Set<String> namen = new HashSet<>();
namen.add("Anna");
namen.add("Anna"); // wird ignoriert
- Keine Garantie auf Reihenfolge (
HashSet
) - Geordnete Version:
LinkedHashSet
(Einfügereihenfolge) - Sortierte Version:
TreeSet
(automatisch sortiert)
Map
Eine Map
speichert Schlüssel-Wert-Paare (key -> value
) und jeder Schlüssel ist einzigartig.
Beispiel:
Map<Integer, String> personen = new HashMap<>();
personen.put(1, "Anna");
personen.put(2, "Ben");
personen.put(1, "Clara"); // überschreibt Anna!
- Zugriff über
get(key)
HashMap
: keine ReihenfolgeLinkedHashMap
: EinfügereihenfolgeTreeMap
: sortiert nach Schlüssel
Klassenbibliothek
Eine Klassenbibliothek (oft auch Klassenbibliothek oder im Englischen class library) ist in der Softwareentwicklung eine Sammlung von vordefinierten Klassen, Funktionen, Schnittstellen und Datentypen, die wiederverwendet werden können, um bestimmte Aufgaben zu lösen oder bestimmte Funktionalitäten bereitzustellen.
Was genau steckt dahinter?
Stell dir eine Klassenbibliothek wie eine Werkzeugkiste vor:
- Du musst nicht jedes Mal den Schraubenzieher neu erfinden.
- Stattdessen greifst du auf eine Sammlung fertiger Werkzeuge zurück.
- Genauso musst du in der Programmierung nicht jedes Mal alles selbst schreiben – du verwendest bestehende Klassen aus einer Bibliothek.
Deklaration & Initialisierung
Deklaration
Beim Deklarieren einer Variable wird dem Programm mitgeteilt, welcher Typ von Daten gespeichert werden soll, aber es wird noch kein konkreter Wert zugewiesen:
int zahl; // Es wird Speicherplatz für eine Ganzzahl reserviert, aber noch kein Wert gesetzt
Initialisierung
Beim Initialisieren wird der Variable ein konkreter Wert zugewiesen:
zahl = 5; // Jetzt wird der Wert 5 im vorher reservierten Speicher abgelegt
Kombiniert
Deklaration und Initialisierung lassen sich auch in einer Zeile zusammenfassen:
int zahl = 5;
Rekursive Funktion
Was ist eine rekursive Funktion?
Eine rekursive Funktion ist eine Funktion, die sich selbst aufruft, um ein Problem Schritt für Schritt zu lösen. Dabei gibt es immer eine Abbruchbedingung, damit die Funktion nicht unendlich weiterläuft.
Beispiel: Kennzeichen erstellen
Ein Programm soll ein zufälliges Kennzeichen generieren.
Es prüft dann, ob dieses bereits vergeben ist.
- Wenn ja, wird ein neues Kennzeichen generiert.
- Wenn nein, wird es gespeichert und zurückgegeben.
String generiereKennzeichen() {
String kennzeichen = zufallsKennzeichen();
if (existiertBereits(kennzeichen)) {
// Rekursiver Aufruf: Funktion ruft sich selbst erneut auf
return generiereKennzeichen();
}
speichereKennzeichen(kennzeichen);
return kennzeichen;
}