Samstag, 27. Juli 2019

Die Annotation @Override

Die Annotation @Override dürfte die Annotation sein, die ich am häufigsten verwende, denn ich finde sie wahnsinnig nützlich. Leider kennen viele Programmierer sie nicht und deswegen möchte ich sie als erstes vorstellen.

Eine Studentengruppe kam einmal zu mir und bat mich um Hilfe, weil ihre toString()-Methode nicht funktionierte. Nicht ihre überschreibende Methode wurde aufgerufen, sondern die Methode toString() von Object, also diejenige, welche die Speicheradresse des Objekts ausgibt.

Der Fehler war relativ einfach: Sie hatten die Methode falsch benannt. Statt sie toString() zu nennen, hatten sie sich verschrieben und die Methode hatte den Namen tostring(). Ein kleiner Fehler mit großer Wirkung, denn die Laufzeitumgebung konnte nicht erkennen, dass hier eine Methode aus der Klasse Object überschrieben werden sollte. Und an dieser Stelle kommt @Override ins Spiel, denn hätten die Studenten diese Annotation benutzt, hätten sie nicht mehrere Stunden nach diesem Fehler gesucht.

Sehen Sie sich mal den folgenden Code an:

public class MySuperClass {
    public void method() {
        System.out.println("method() in MySuperClass");
   }
}

public class MySubClass {
    public void metod() {
        System.out.println("method() in MySubClass");
   }
}


Ich möchte gerne die Methode method() in der Unterklasse überschreiben. Aber wie in meinem oben beschriebenen Beispiel habe ich mich verschrieben. Der Compiler bemerkt das nicht und erzeugt zwei unterschiedliche Methoden. Somit bekomme ich wegen meines kleinen Schreibfehlers einen ziemlich doofen Laufzeitfehler, der unter Umständen schwer zu finden ist. Im folgenden Code habe ich die Annotation @Override eingebaut.

public class MySuperClass {
    public void method() {
        System.out.println("method() in MySuperClass");
   }
}

public class MySubClass {
  @Override
  public void metod() {
        System.out.println("method() in MySubClass");
   }
}


Mit dieser Annotation sage ich dem Compiler: "He, Compiler. Ich glaube, ich überschreibe da eine Methode. Aber pass mal lieber mit auf!" Und in meinem Beispiel wird der Compiler jetzt maulen und sagen, dass er die Methode metod() nicht überschreiben kann, weil es sie in der Oberklasse nicht gibt. Und schon habe ich aus einem potentiellen Laufzeitfehler einen Übersetzungszeitfehler gemacht. Und wenn der Compiler einen Fehler finden kann, ist das Gold wert, denn ich erhalte überhaupt kein lauffähiges Programm. Laufzeitfehler suchen kann erheblich mühsamer werden.

Das tut die Annotation @Override: Sie markiert eine Methode für den Compiler mit dem Hinweis, dass diese Methode überschrieben werden soll. Diese Annotation hat gleich mehrere Vorteile:


  1. Wie schon beschrieben erhalten wir einen Compilerfehler, wenn wir eine Methode nicht überschreiben. Damit sind Schreibfehler schon einmal ausgeschlossen. Zudem können wir den Compilerfehler auch nutzen, wenn wir uns unsicher sind, ob diese Methode wirklich in der Oberklasse existiert.
  2. Dokumentation: Programmierer dokumentieren ja normalerweise eher ungerne - eine Eigenart, die ihre Software nicht unbedingt besser macht. Die Information, ob eine Methode überschrieben wird, ist jedoch sehr wichtig und sollte dokumentiert werden. Wenn wir @Override verwenden, bekommen wir die Dokumentation also frei Haus mit geliefert.
  3. Wenn der Name der überschriebenen Methode in der Oberklasse ändert, bekommen das die Klassen, die Methoden überschreiben möchten, normalerweise nicht mit. Hier ist also Vorsicht und Umsicht von Seiten des Programmierers angesagt - darauf sollte man sich nicht verlassen. Mit @Override passt der Compiler mit uns zusammen auf. 
  4. Gute IDEs wie Eclipse oder NetBeans können die Annotation nutzen, um Sie als Programmierer zu unterstützen. Mal angenommen, Sie schreiben eine Klasse, die ein Interface implementieren soll. Das Interface existiert bereits, aber es enthält die Methodendeklarationen noch nicht. Dann implementieren Sie die Methode in der Klasse, klatschen @Override darüber und die IDE legt dann die Methode im Interface an. Das ist ziemlich praktisch.
Grundsätzlich sollten Sie @Override immer verwenden, wenn Sie eine Methode überschreiben oder eine abstrakte Methode implementieren. Sie sehen oben, dass die Annotation auch Vorteile mit sich bringt, wenn man sich ganz sicher ist, dass man sich beim Methodennamen nicht verschrieben hat. Ich persönlich verwende @Override auch bei toString() und equals(). Diese Annotation ist einfach, aber unglaublich praktisch. 

Keine Kommentare:

Kommentar veröffentlichen