CodeGym /Kursy /JAVA 25 SELF /Pojęcie dziedziczenia, składnia extends

Pojęcie dziedziczenia, składnia extends

JAVA 25 SELF
Poziom 17, Lekcja 0
Dostępny

1. Czym jest dziedziczenie?

Dziedziczenie to mechanizm, który pozwala tworzyć nową klasę na podstawie już istniejącej, „dziedzicząc” jej właściwości i metody. Nowa klasę nazywamy podklasą (klasą potomną), a klasę wyjściową — klasą bazową (rodzicem).

To tak, jak gdybyś robił nowy tort na podstawie starego przepisu: bierzesz wszystko, co najlepsze, dodajesz kilka nowych składników – i voilà, masz już „Tort według babcinego przepisu z sekretnym składnikiem”.

  • Klasa bazowa — zawiera wspólne właściwości i zachowania.
  • Podklasa — dziedziczy to wszystko, a ponadto może dodać coś własnego albo zmienić zachowanie.

Oto przykład: „Kot to Zwierzę”. Wszystkie koty są zwierzętami, ale nie wszystkie zwierzęta są kotami. Zwierzę może być klasą bazową, a Kot — jego podklasą. Tak samo jak Pies, na przykład.
Albo „Okrąg to Figura”. Każdy okrąg jest figurą, ale nie każda figura jest okręgiem. Figura może być klasą bazową, a Okrąg i Trójkąt — jej dziedzicami. W Javie takie relacje realizuje się za pomocą słowa kluczowego extends.

Po co jest dziedziczenie?

Pytanie za milion: dlaczego nie skopiować po prostu kodu z jednej klasy do innej? Dlaczego w ogóle wymyślono dziedziczenie?

  • Wielokrotne użycie kodu: Wszystko, co wspólne, wynosimy do klasy bazowej. Nie trzeba duplikować pól i metod — automatycznie pojawiają się w podklasach. Na przykład w aplikacji dla uniwersytetu klasą bazową może być człowiek, który ma co najmniej imię i datę urodzenia, a „student” i „wykładowca” — to podklasy z własnymi właściwościami.
  • Rozszerzanie i specjalizacja: Można dodać nowe właściwości i metody albo zmienić istniejące tylko tam, gdzie to potrzebne. Wszystkie zwierzęta wydają dźwięki, ale kot będzie miauczał, a pies — szczekał. Przy tym kotu można dodać umiejętność wspinania się na drzewa (której klasa bazowa nie ma).
  • Porządkowanie hierarchii: Kod staje się bardziej logiczny i zrozumiały. Na przykład jeśli masz klasy Animal, Dog, Cat, od razu widać, że Dog i Cat to szczególne przypadki Animal.

Przykład. Gdyby w Javie nie było dziedziczenia, musiałbyś kopiować metody takie jak eat(), sleep() i pole name do każdej klasy zwierzęcia. A jeśli jutro trzeba będzie dodać metodę breathe(), trzeba zmieniać dziesiątki klas! Z dziedziczeniem — wystarczy dodać „oddychanie” w klasie bazowej.

2. Składnia dziedziczenia: extends

Jak zadeklarować dziedziczenie w Javie? To bardzo proste: użyj słowa kluczowego extends.

class ParentClass {
    // pola i metody
}

class Subclass extends ParentClass {
    // dodatkowe pola i metody
}

Przykład 1: Zwierzęta

// Klasa bazowa
class Animal {
    String name;

    void eat() {
        System.out.println(name + " je.");
    }
}

// Podklasa
class Cat extends Animal {
    void meow() {
        System.out.println(name + " mówi: Miau!");
    }
}

Co się tu dzieje?

  • Klasa Cat dziedziczy wszystkie pola i metody klasy Animal.
  • To znaczy, że Cat ma już pole name i metodę eat(), mimo że ich nie zapisaliśmy jawnie.
  • Oprócz tego Cat ma własną metodę meow().

Użycie

public class Main {
    public static void main(String[] args) {
        Cat kitty = new Cat();
        kitty.name = "Barsik";
        kitty.eat();      // Barsik je.  (odziedziczone)
        kitty.meow();     // Barsik mówi: Miau! (własna metoda)
    }
}

Voilà! Otrzymaliśmy nową klasę przy minimalnej ilości kodu, unikając duplikacji.

3. Co dokładnie dziedziczy podklasa?

W Javie podklasa dziedziczy:

  • Wszystkie publiczne (public) i chronione (protected) pola i metody klasy bazowej.
  • Wszystkie składowe o dostępie package-private, jeśli podklasa jest w tym samym pakiecie.

Nie dziedziczy:

  • Konstruktorów (trzeba je jawnie zadeklarować w podklasie).
  • Prywatnych (private) pól i metod (są dostępne tylko wewnątrz samej klasy bazowej).
  • Statycznych bloków inicjalizacji (nie są dziedziczone, ale każda klasa może mieć własne).
  • Składowych package-private, jeśli podklasa znajduje się w innym pakiecie.

Ilustracja

class Animal {
    public String name;
    private int age;

    public void eat() { 
        System.out.println("Jem"); 
    }
    private void secret() { 
        System.out.println("Sekret!"); 
    }
}

class Dog extends Animal {
    public void bark() { 
        System.out.println("Hau!"); 
    }
}
  • Dog odziedziczy pole name i metodę eat().
  • Dog nie widzi pola age i metody secret() — są prywatne.

4. Ograniczenia dziedziczenia w Javie

Java to dość surowa dama i ma własne zasady:

Tylko pojedyncze dziedziczenie klas: każda klasa może dziedziczyć tylko po jednej innej klasie. Za to klasa może mieć dowolnie wielu dziedziców.

class Dog extends Animal { ... } // OK
class Dog extends Animal, Pet { ... } // Błąd! Tak nie można

Wielokrotne dziedziczenie interfejsów — można, ale to osobna historia i porozmawiamy o tym później.

Klasa Object — pramatka wszystkich klas w Javie. Nawet jeśli jawnie nie piszesz extends, Twoja klasa i tak niejawnie dziedziczy po Object.

5. Praktyczny przykład

Kontynuujmy budowę naszej „zoologicznej” aplikacji.

Krok 1. Klasa bazowa Animal

class Animal {
    String name;

    void eat() {
        System.out.println(name + " je.");
    }
}

Krok 2. Podklasa Cat

class Cat extends Animal {
    void meow() {
        System.out.println(name + " mówi: Miau!");
    }
}

Krok 3. Podklasa Dog

class Dog extends Animal {
    void bark() {
        System.out.println(name + " mówi: Hau!");
    }
}

Krok 4. Używamy klas

public class Main {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.name = "Murka";
        cat.eat();   // Murka je.
        cat.meow();  // Murka mówi: Miau!

        Dog dog = new Dog();
        dog.name = "Sharik";
        dog.eat();   // Sharik je.
        dog.bark();  // Sharik mówi: Hau!
    }
}

Co uzyskaliśmy?

  • Obie klasy Cat i Dog używają wspólnego pola name i metody eat() z klasy bazowej.
  • Każda klasa dodaje swoje unikalne zachowanie: meow() dla kota, bark() dla psa.
  • Jeśli trzeba zmienić sposób, w jaki zwierzęta jedzą, wystarczy zmienić metodę eat() w klasie Animal — zmiany automatycznie obejmą wszystkich dziedziców.

6. Przydatne niuanse

Wizualizacja: hierarchia klas

Hierarchię można sobie wyobrazić tak:

.        Animal
        /    \
     Cat     Dog
  • Animal — klasa bazowa, zawiera wszystko, co wspólne dla zwierząt.
  • Cat i Dog — podklasy, dodają unikalne cechy.

Kilka słów o konstruktorach i dziedziczeniu

Konstruktory nie są dziedziczone. Jeśli nie definiujesz konstruktora w podklasie, Java automatycznie doda konstruktor bez parametrów (o ile istnieje u rodzica). Jeśli klasa bazowa ma tylko konstruktor z parametrami, to w podklasie trzeba go wywołać jawnie przez super(...). Krótki przykład:

class Animal {
    String name;
    Animal(String name) {
        this.name = name;
    }
}

class Cat extends Animal {
    Cat(String name) {
        super(name); // wywołujemy konstruktor klasy bazowej
    }
}

7. Typowe błędy przy użyciu dziedziczenia

Błąd nr 1: Próba dziedziczenia jednocześnie po kilku klasach.
W Javie nie można napisać class Cat extends Animal, Pet. Tylko jeden rodzic!

Błąd nr 2: Oczekiwanie, że prywatne pola i metody będą dostępne w podklasie.
Prywatne składowe nie są dziedziczone (ściślej: istnieją, ale nie ma do nich dostępu z podklasy). Użyj protected, jeśli chcesz zezwolić dziedzicom na dostęp.

Błąd nr 3: Zapomniane wywołanie konstruktora klasy bazowej.
Jeśli w klasie bazowej nie ma konstruktora bez parametrów, a nie wywołujesz jawnie super(...), pojawi się błąd kompilacji.

Błąd nr 4: Używanie dziedziczenia „dla oszczędności kodu”, a nie ze względów semantycznych.
Jeśli między klasami nie ma relacji „jest” (is-a), lepiej nie używać dziedziczenia. Na przykład „Człowiek” nie powinien dziedziczyć po „Samochodzie”, nawet jeśli obie mają pole speed.

1
Zadanie
JAVA 25 SELF, poziom 17, lekcja 0
Niedostępne
Szkolenie wirtualnego pupila: Kocie zwyczaje 🐾
Szkolenie wirtualnego pupila: Kocie zwyczaje 🐾
1
Zadanie
JAVA 25 SELF, poziom 17, lekcja 0
Niedostępne
Psi wierność: Sen i szczekanie w wirtualnym świecie 🐶
Psi wierność: Sen i szczekanie w wirtualnym świecie 🐶
1
Zadanie
JAVA 25 SELF, poziom 17, lekcja 0
Niedostępne
Flota firmy: Uruchamianie samochodów 🚗
Flota firmy: Uruchamianie samochodów 🚗
1
Zadanie
JAVA 25 SELF, poziom 17, lekcja 0
Niedostępne
Owocowy sklep: Kolorowe dary natury 🍎🍌
Owocowy sklep: Kolorowe dary natury 🍎🍌
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION