Spis treści
Gdy rozszerzamy klasę, dziedziczymy po niej pola i metody, które mają modyfikatory public lub protected. Do tej pory nie korzystaliśmy z modyfikatora protected, ponieważ dopiero w tym rozdziale poznajemy mechanizm dziedziczenia.
Spójrzmy na poniższe klasy:
package pojazdy; public class Pojazd { public void jedz() { // 1 System.out.println("Pojazd jedzie."); } }
package pojazdy; public class Samochod extends Pojazd { protected int liczbaKol; // 2 }
package pojazdy; public class SamochodWyscigowy extends Samochod { public SamochodWyscigowy() { this.liczbaKol = 4; // 3 } public String toString() { return "Samochod wyscigowy, liczba kol: " + liczbaKol; // 4 } }
Klasa SamochodWyscigowy rozszerza klasę Samochod. Klasa Samochod posiada jedno pole z modyfikatorem protected (2), które klasa SamochodWyscigowy po niej dziedziczy – ustawiamy je w konstruktorze tej klasy (3) oraz wypisujemy w metodzie toString (4).
Ponadto, klasa SamochodWyscigowy dziedziczy pośrednio po klasie Pojazd, która ma jedną publiczną metodę jedz (1). Tę metodę klasa SamochodWyscigowy także dziedziczy. Zobaczmy, jak moglibyśmy użyć tej klasy:
package pojazdy; public class TorWyscigowy { public static void main(String[] args) { SamochodWyscigowy wyscigowy = new SamochodWyscigowy(); System.out.println(wyscigowy); wyscigowy.jedz(); } }
Klasa TorWyscigowy tworzy obiekt klasy SamochodWyscigowy, a następnie wypisuje jego tekstową reprezentację na ekran i wywołuje na nim metodę jedz. Metody tej, jak widzieliśmy wcześniej, nie ma w klasie SamochodWyscigowy – jest ona zdefiniowana w klasie Pojazd. To z tej klasy metoda jedz jest dziedziczona przez klasę SamochodWyscigowy. Wynik działania tego programu:
Zarówno pól i metod prywatnych, jak i tych z dostępem domyślnym (tzn. gdy nie mają one zdefiniowanego żadnego modyfikatora dostępu), nie dziedziczy się. Próba odniesienia się z klasy pochodnej do pola bądź metody private, zdefiniowanych w klasie bazowej, kończy się błędem kompilacji:
package pojazdy; public class Pojazd { private String rejestracja; // 1 public void jedz() { System.out.println("Pojazd jedzie."); } }
package pojazdy; public class SamochodWyscigowy extends Samochod { public SamochodWyscigowy() { this.liczbaKol = 4; // blad! // pole rejestracja jest prywatne, więc nie jest dziedziczone! this.rejestracja = "KJ-777"; // 2 } public String toString() { return "Samochod wyscigowy, liczba kol: " + liczbaKol; } }
Do klasy Pojazd dodałem prywatne pole rejestracja (1). Próba ustawienia tego pola w konstruktorze klasy SamochodWyscigowy kończy się błędem kompilacji:
Jeżeli klasa pochodna jest w tym samym pakiecie, co jej klasa bazowa, to będzie mimo wszystko miała dostęp do pól i metod z domyślnym modyfikatorem dostępu – w końcu takie właśnie zastosowanie ma ten modyfikator. Do modyfikatora domyślnego wrócę w jednym z kolejnych podrozdziałów.