Statische Typsysteme
Statisches Typsystem
Die Datentypen von Variablen, Parametern und Rückgabewerten von Methoden müssen im Quelltext festgelegt werden. Daher kann der Compiler überprüfen, ob Zuweisungen gültig sind oder ob ein Kompilierungsfehler angezeigt werden muss.
Vorteile statischer Typsysteme
- Zur Laufzeit müssen keine Typüberprüfungen mehr stattfinden, was die Ausführung des Programms beschleunigt.
- Der Quelltext des Programms ist übersichtlicher, durch die Typisierung wird klar, welche Bedeutung welche Variable und welcher Parameter haben.
- Fehler im Programm werden bereits vor dem Kompilieren erkannt.
Programmiersprachen mit statischen Typsystemen
Die bekanntesten Programmiersprachen mit einem statischen Typsystem sind
Java, C++, C#
Weniger stark verbreitet sind TypeScript, Go, Rust, Kotlin, Swift und Scala, um nur einige zu nennen.
Dynamische Typsysteme
Dynamisches Typsystem
Die Datentypen von Variablen, Parametern und Rückgabewerten von Methoden werden im Quelltext nicht festgelegt.
Vorteile dynamische Typsysteme
- Mehr Flexibilität beim Programmieren - der Typ einer Variablen kann sich zur Laufzeit ändern. Das erlaubt mehr generischen Code und dynamisches Verhalten.
- Weniger Schreibaufwand - man spart sich Typdeklarationen, vor allem bei Sammlungen wie ArrayList oder den Rückgabetypen von Methoden.
Statt einer Operation wie String eintrag = (String) liste.getFirst(); kann man einfach schreiben: eintrag = liste.getFirst(); - Einfacheres Prototyping - man kann den Code schneller ausprobieren, ohne sich um Typdetails kümmern zu müssen (rapid prototyping).
Programmiersprachen mit dynamischen Typsystemen sind
Python, JavaScript, Ruby und PHP
Nicht ganz so bekannt und verbreitet sind Lua, R, Perl und das uralte Smalltalk, die "Mutter aller objektorientierten Programmiersprachen".
Vergleich an einem konkreten Beispiel
Ich habe ChatGPT den Auftrag gegeben, ein Java- und ein Python-Beispiel für die Division von zwei Zahlen mit Fehlerüberprüfung zu generieren. Hier die Ergebnisse.
Java
public class Division { public void dividiere(int zaehler, int nenner) { if (nenner != 0) { double ergebnis = (double) zaehler / nenner; System.out.println("Ergebnis: " + ergebnis); } else { System.out.println("Fehler: Division durch 0 ist nicht erlaubt."); } } }
Hier sieht man sehr schön die notwendigen Typdeklarationen, allein in dem Kopf der Methode dividieren sind drei Deklarationen notwendig:
public void dividiere(int zaehler, int nenner)
Das Ergebnis ist dann vom Typ double, und da die Division zweier Ganzahlen in Java stets eine neue Ganzzahl ergibt, muss auch noch ein Typecasting durchgeführt werden, um eine Fließkommazahl zu erhalten:
double ergebnis = (double) zaehler/nenner;
Kommen wir nun zu dem Python-Quelltext, den ChatGPT generiert hat:
Python
def dividiere(zaehler, nenner): if nenner != 0: ergebnis = zaehler / nenner print("Ergebnis:", ergebnis) else: print("Fehler: Division durch 0 ist nicht erlaubt.") # Beispiele: dividiere(7, 2) # Ausgabe: Ergebnis: 3.5 dividiere(5, 0) # Ausgabe: Fehler: Division durch 0 ist nicht erlaubt.
Hier wird an keiner Stelle im Quelltext ein Datentyp definiert. Wenn die Ganzzahl 7 durch die Ganzzahl 2 dividiert wird, ist das Ergebnis die Fließkommazahl 3.5.
Quellen:
- Lahres et al.: Objektorientierte Programmierung, Rheinwerk Computing 2021.
- Barnes, Kölling: Java lernen mit BlueJ - Objects first. Pearson-Verlag 2019.
- Ullenboom: Java ist auch eine Insel, Rheinwerk Computing 2023.