Dieser Begriff bezieht sich auf den Kontrakt, der zwischen einer Methode und den Benutzern dieser Methode besteht.
In diesem Kontrakt wird u.a. festgelegt, welche Vorbedingungen ein Aufrufer der Methode einhalten oder schaffen muss, bevor die Methode ausgeführt werden kann. Sind diese Vorbedingungen nicht erfüllt, so kann man nicht davon ausgehen, dass die Methode korrekt oder überhaupt arbeitet.
Die Vorbedingungen und die Nachbedingungen bilden zusammen mit den Invarianten den Kontrakt (Vertrag) der Methode (siehe auch Design-by-contract-Prinzip).
Beispiele
Beispiel 1a
public int[] getElement(int[] list, int i) { return list[i]; }
Hier muss der Benutzer der Methode selbst prüfen, dass der übergebene Array nicht null ist und dass der übergebene Index im gültigen Bereich >= 0 und < list.length liegt, andernfalls arbeitet die Methode nicht korrekt. Es müssen also zwei Vorbedingungen erfüllt sein, die vom Benutzer einzuhalten sind.
Beispiel 1b
public int[] getElement(int[] list, int i) { if (list != null) throw new IllegalArgumentException("Array darf nicht null sein"); if (i < 0 || i >= list.length) throw new IndexOutOfBoundsException("Index außerhalb des gültigen Bereichs" return list[i]; }
In dieser Variante der Methode übernimmt die Methode selbst eine solche Überprüfung und "wirft" Fehlermeldungen, wenn die Vorbedingungen nicht eingehalten worden sind. Der Benutzer der Methode muss nichts überprüfen, also hat diese Methode auch keine Vorbedingungen.
Obwohl - man könnte hier natürlich einwenden, dass es nicht Sinn und Zweck der Methode ist, Fehlermeldungen zu produzieren. Damit dies nicht passiert und die Methode ihren eigentlichen Zweck erfüllen kann, sind durchaus zwei Vorbedingungen einzuhalten.
Beispiel 2a
public double quotient(double zaehler, double nenner) { if (nenner == 0) throw new IllegalArgumentException("Nenner darf nicht 0 sein"); else return zaehler/nenner;}
Keine Vorbedingungen, die Methode überprüft selbst, ob der Nenner einen gültigen Wert hat.
Beispiel 2b
public double quotient(double zaehler, double nenner) { return zaehler/nenner;}
Die Methode verlässt sich darauf, dass die Vorbedingung nenner != 0 erfüllt ist.
Beispiel 3
// Diese Methode führt eine binäre Suche nach der gesuchten Zahl durch public int contains(int[] zahlen, int suchzahl) { // Der Quelltext }
Hier sind zwei Vorbedingungen zu erfüllen. Erstens darf der Array zahlen nicht null sein, zweitens muss der Array sortiert sein, weil sonst keine binäre Suche stattfinden kann, die im Kommentar "versprochen" wurde. An diesem Beispiel kann man gut sehen, welche wichtige Rolle Kommentare bei der Formulierung von Vorbedingungen und Nachbedingungen spielen.
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.