Programowanie średniozaawansowane #3: przesłanianie metod za pomocą @Override

W dzisiejszej lekcji poznasz swoją pierwszą adnotację, którą będzie Override. Adnotacje tak jak obiekty są typami referencyjnymi. Nie będę wnikał w jaki sposób się je tworzy, bo jest to wiedza zaawansowana, na dzień dzisiejszy kompletnie Ci nieprzydatna. Adnotacje w Javie możesz traktować jak swego rodzaju specjalne parametry, które nie wpływają w żaden sposób na logikę implementacji (czyli z punktu biznesowego nie mają one wpływu), ale skutecznie zmieniają zachowanie kodu od strony technicznej. Najprostszym i jeden przykładem adnotacji, którą będziesz w przyszłości często używać jest @Override.

Na pierwszy rzut oka już widać coś szczególnego w adnotacja, a mianowicie konwencja nazewnicza. Otóż przed każdą nazwą adnotacji stoi znak małpy (czyli @). Adnotacje stawiamy w linijce przed kodem Javy. Mogą być one użyte praktycznie wszędzie (od nazw metod, przez klasy, do nazwy pól, itp.), w zależności od ich przeznaczenia. Z reguły współgrają one z różnego rodzajami narzędzi (frameworków). Omówię teraz adnotację override, którą widzisz na przykładzie poniżej.

public class ChildOne extends Parent{
  private String name;

  public ChildOne(String parentName, String name) {
    super(parentName);
    this.name = name;
  }

  @Override
  public void showName() {
    System.out.println("Dziecko nazywa się " + name);
  }
}

Kod poza adnotacją nie różni się od poprzedniej wersji. Jeśli ją usuniesz to sonar (popularne narzędzie do pomocy w programowaniu), pokaże Ci taki komunikat: „Add the „@Override” annotation above this method signature„. Dlaczego tak się dzieje i do czego ta adnotacja może być pomocna? Sprawia ona, że kompilator określa, czy oznaczoną nią metoda na pewno przesłania (override) metodę z klasy rodzica. Mówiąc wprost, dokonuje ona sprawdzenia na wypadek jeśli pomylisz się w sygnaturze.

Przeanalizuj poniższy przykład:

public class Parent {
  private String name;
  public Parent(String name) {
    this.name = name;
  }

  public void showName() {
    System.out.println("Rodzic nazywa się " + name);
  }
  
  public void showAge(Integer age) {
    System.out.println("Rodzic ma lat " + age);
  }
}

public class ChildOne extends Parent {
  private String name;

  public ChildOne(String parentName, String name) {
    super(parentName);
    this.name = name;
  }

  @Override
  public void showName() {
    System.out.println("Dziecko nazywa się " + name);
  }

  @Override
  public void showAge(Long age) {
    System.out.println("Dziecko ma lat " + age);
  }
}

W przypadku metody showName przesłonienie zadziała, bo sygnatura jest dokładnie taka sama. Niestety metoda showAge zawiera inny typ parametru niż rodzic (Long zamiast Integer), co sprawia, że sygnatury nie są takie same, a zatem polimorfizm w tym przypadku nie zadziała. Deklaracja adnotacji override nad metodami przesłaniającymi, eliminuje możliwość popełnieniu głupiego błędu podczas implementacji. Stosuj ją zawsze, gdy używasz polimorfizm!

Dodaj komentarz