Dlaczego wywołanie metod publicznych w konstruktorach potrafi być niebezpieczne?
Dlaczego wywołanie metod publicznych w konstruktorach potrafi być niebezpieczne?
public class Figura { int day; public Figura() { day = getLiczba(); } public int getLiczba() { return 2; } public void showInfo() { System.out.println("Dzisiaj jest dzien: " + day); } } public class Kolo extends Figura { int koloLiczba; public Kolo() { koloLiczba = 5; } public int getLiczba() { return koloLiczba; } } public class Start { public static void main(String[] args) { Kolo k = new Kolo(); k.showInfo(); } }
Po wykonaniu powyższego fragmentu kodu otrzymujemy niespodziewanie wynik: "Dzisiaj jest dzien: 0". Twórca klasy Figura zakładał, że zostanie wywołana metoda "getLiczba", która zwróci wartość 2. Nie przewidział jednak, że ktoś może odziedziczyć po klasie Figura.
Z chwilą wykonania linii "Kolo k = new Kolo();" nastąpiło najpierw wywołanie konstruktora klasy Figura. Ponieważ zachodzi dziedziczenie, w ramach jego wywołania nastąpiło wywołanie metody "getLiczba" z klasy Kolo. Tu występuje problem, ponieważ konstruktor klasy Kolo nie został jeszcze wywołany. W efekcie, metoda "getLiczba" z klasy Kolo zwraca 0. Wartość ta jest przypisana do zmiennej "day" w konstruktorze klasy Figura. W efekcie, metoda "showInfo" wyświetla nam zero w komunikacie.
Powyższy przykład pokazuje nam, że wywoływanie metod publicznych w konstruktorach potrafi sprawiać problemy. Jeżeli już wywołujemy jakiekolwiek metody w konstruktorze, powinny one być raczej prywatne.