Problem z dziedziczeniem

0

abstract public class Unit {
private int attack;
public int getAttack () {
return attack;
}
}

class Unit1 extends Unit {
private int attack = 2;
}

class Unit2 extends Unit {
private int attack = 4;
}


Unit1 unit = new Unit1();
unit.getAttack(); // 0!

Witam dlaczego zwraca 0? Wyglada na to ze on mi zwraca attack rodzica (jak zmienie w klasie Unit attack na np. 6 to to wywołanie mi zwroci 6). Ale jak mu powiedziec ze ma mi zwrocic atak Unitu1 czy Unitu2?

0

Teraz powinno być dobrze

 
abstract public class Unit {
        protected int attack;
        public int getAttack () {
              return attack;
       }

}


class Unit1 extends Unit {

public Unit1() {
    attack = 2;
}

}

class Unit2 extends Unit {
   public Unit2() {
    attack = 4;
}
}
0

na to wpadlem ale to glupota pisac w kazdej na nowo getAttack. Po to jest dziedziczenei zeby skracac kod. Nie mozna zrobic bez przepisywania metod?

0

To w ogóle jest bez sensu. Dziedziczenie stosujesz kiedy te obiekty się czymś różnią, a u ciebie są identyczne tylko mają inne wartości pól, a to się za bardzo do dziedziczenie nie kwalifikuje...

1

Wstawianie pól o tej samej nazwie do klas dziedziczących jest bez sensu ponieważ nie jest to jak w przypadku metody "zmiana" (czyli przesłonięcie), lecz dodanie nowego pola (przeciążenie). U Ciebie pierwsze pole nazywa się Unit.attack, a następne Unit1.attack lub Unit2.attack. Oznacza to, że w Unit1 masz dwa pola: Unit.attack (niedostępne) i Unit1.attack. Pierwsze z nich nie jest przez Ciebie jawnie zainicjowane, więc robi to za Ciebie kompilator inicjując pole Unit.attack wartością 0. Stąd taka zwracana wartość. Drugie pole jest już jawnie inicjowane wartością 2 (lub 4) - i taką wartość dostaniesz jeżeli tego pola użyjesz. Gdy w metodzie użyjesz nazwy pola bez kwalifikatora klasy, to domyślnie brana jest klasa, w której znajduje się ta metoda. Dlatego w metodzie Unit.getAttack dostawałeś wartość 0 (z Unit.attack).
Gdy przesłoniłeś (jak piszesz) metodę getAttack w klasie Unit1 lub Unit2, to otrzymałeś z ich wywołania wartości 2 lub 4 bo odwołują się one do zupełnie innych pól: Pierwsze z klasy bazowej, a drugie z dziedziczącej.

Jako taki przykład podał Ci po wielu edycjach Robcio. Tyle, że w nim jedna metoda publiczna odwołuje się do tego samego pola (bo protected), tylko inaczej inicjowanego w klasach dziedziczących. Ale częściej używanym rozwiązaniem jest coś odwrotnego - metodę z klasy publicznej przesłania się wersjami z klas dziedziczących i wtedy ta dziedziczona wersja zwraca sobie te inne wartości. Wtedy pole attack może być prywatne, albo wręcz nie musi istnieć - będzie to prywatna sprawa każdej klasy co sobie jej metoda (lub jej lokalnie przesłonięta wersja) zwróci (np. stałą liczbę 2 lub 4, bez odwoływania się do pól).

1 użytkowników online, w tym zalogowanych: 0, gości: 1