Menu
Coddy logo textTech

Dziedziczenie jedno- i wielopoziomowe

Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 25 z 87.

Do tej pory widzieliśmy klasy bezpośrednio dziedziczące po jednej klasie nadrzędnej. Dziedziczenie może jednak przyjmować różne struktury w zależności od relacji między klasami. Przyjrzyjmy się dwóm głównym wzorcom: dziedziczeniu pojedynczemu i dziedziczeniu wielopoziomowemu.

Dziedziczenie pojedyncze to rodzaj dziedziczenia, którego używaliśmy. Klasa bezpośrednio rozszerza dokładnie jedną klasę nadrzędną:

public class Animal { }
public class Dog extends Animal { }
public class Cat extends Animal { }

Tutaj zarówno Dog, jak i Cat dziedziczą po Animal, ale nie dziedziczą po sobie nawzajem. Każda klasa potomna ma jedną bezpośrednią klasę nadrzędną.

Dziedziczenie wielopoziomowe tworzy łańcuch, w którym jedna klasa dziedziczy po innej klasie, która z kolei dziedziczy po kolejnej klasie:

public class Animal {
    public void eat() {
        System.out.println("Eating");
    }
}

public class Mammal extends Animal {
    public void breathe() {
        System.out.println("Breathing");
    }
}

public class Dog extends Mammal {
    public void bark() {
        System.out.println("Barking");
    }
}

W tym łańcuchu Dog dziedziczy po Mammal, który dziedziczy po Animal. Obiekt Dog ma dostęp do wszystkich metod z całego łańcucha:

Dog dog = new Dog();
dog.eat();      // Z klasy Animal
dog.breathe();  // Z klasy Mammal
dog.bark();     // Z klasy Dog

Pamiętaj, że Object znajduje się na szczycie każdego łańcucha. Nasz Dog ma więc tak naprawdę cztery poziomy: Object -> Animal -> Mammal -> Dog. Podczas tworzenia nowego obiektu wywołania konstruktorów przechodzą przez wszystkie te poziomy.

challenge icon

Wyzwanie

Łatwy

Stwórzmy hierarchię pojazdów, która pokazuje zarówno dziedziczenie jednopoziomowe, jak i wielopoziomowe. Utworzysz łańcuch klas, w którym każdy poziom dodaje nowe możliwości, pokazując, jak metody są dziedziczone przez wiele poziomów.

Rozmieścisz swój kod w czterech plikach:

  • Vehicle.java: Utwórz klasę bazową na szczycie hierarchii. Każdy pojazd powinien mieć:
    • Prywatne pole przechowujące brand (String)
    • Konstruktor przyjmujący markę
    • Metodę getBrand(), która zwraca markę
    • Metodę move(), która wyświetla: [brand] is moving
  • LandVehicle.java: Utwórz klasę rozszerzającą Vehicle, reprezentującą środkowy poziom twojego wielopoziomowego łańcucha. Pojazdy lądowe dodają zachowanie specyficzne dla poruszania się po ziemi:
    • Prywatne pole przechowujące wheels (int)
    • Konstruktor przyjmujący markę i liczbę kół, używający super(brand) dla części klasy nadrzędnej
    • Metodę getWheels(), która zwraca liczbę kół
    • Metodę honk(), która wyświetla: [brand] honks!
  • Car.java: Utwórz klasę rozszerzającą LandVehicle, uzupełniającą trzy poziomy łańcucha dziedziczenia. Samochody dodają własne specjalistyczne cechy:
    • Prywatne pole przechowujące model (String)
    • Konstruktor przyjmujący markę, liczbę kół i model, używający super(brand, wheels)
    • Metodę getModel(), która zwraca model
    • Metodę displayInfo(), która wyświetla: [brand] [model] with [wheels] wheels
  • Main.java: Pokaż, jak obiekt Car ma dostęp do metod ze wszystkich trzech poziomów hierarchii. Otrzymasz trzy dane wejściowe: markę (String), liczbę kół (int) i model (String). Utwórz obiekt Car i wywołaj kolejno te metody:
    • move() — odziedziczona z Vehicle (dziadka)
    • honk() — odziedziczona z LandVehicle (rodzica)
    • displayInfo() — zdefiniowana w samej klasie Car

Otrzymasz trzy dane wejściowe: nazwę marki, liczbę kół i nazwę modelu.

Wynik powinien zawierać trzy wiersze pokazujące, jak obiekt Car może korzystać z metod z każdego poziomu swojego łańcucha dziedziczenia — od najwyższego poziomu Vehicle aż po własną klasę!

Spróbuj swoich sił

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Odczytaj dane wejściowe
        String brand = scanner.nextLine();
        int wheels = scanner.nextInt();
        scanner.nextLine(); // odczytaj znak nowej linii
        String model = scanner.nextLine();
        
        // TODO: Utwórz obiekt Car z wartościami wejściowymi
        
        // TODO: Wywołaj move() — odziedziczoną po Vehicle (klasie nadrzędnej klasy nadrzędnej)
        
        // TODO: Wywołaj honk() — odziedziczoną po LandVehicle (klasie nadrzędnej)
        
        // TODO: Wywołaj displayInfo() — zdefiniowaną w samej klasie Car
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Java online