Home > Informatik > Begriffe und Konzepte > Typsysteme

Typsysteme

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:

  1. Lahres et al.: Objektorientierte Programmierung, Rheinwerk Computing 2021.
  2. Barnes, Kölling: Java lernen mit BlueJ - Objects first. Pearson-Verlag 2019.
  3. Ullenboom: Java ist auch eine Insel, Rheinwerk Computing 2023.