CodeGym /Blog Java /Random-PL /Dziedziczenie w Javie
John Squirrels
Poziom 41
San Francisco

Dziedziczenie w Javie

Opublikowano w grupie Random-PL
Java jest językiem obiektowym. Oznacza to, że wszystko w Javie składa się z klas i ich obiektów i jest zgodne z paradygmatami OOP (programowanie obiektowe). Jednym z takich paradygmatów jest dziedziczenie – mechanizm w Javie, dzięki któremu jedna klasa może dziedziczyć cechy (pola i metody) innej klasy. Mówiąc najprościej, w Javie dziedziczenie oznacza tworzenie nowych klas w oparciu o istniejące. Dziedziczenie w Javie - 1

Kluczowi aktorzy dziedziczenia w Javie

  • Dziedziczenie to koncepcja mówiąca, że ​​klasa może częściowo lub całkowicie powtarzać właściwości i metody swojego rodzica (klasy, z której dziedziczy).
  • Klasa potomna, podklasa, klasa rozszerzona lub klasa pochodna to klasa, która dziedziczy z innej klasy.
  • Klasa nadrzędna, nadklasa lub klasa bazowa to klasa posiadająca wiele funkcji, które mogą być przekazywane (dziedziczone) przez inną klasę (klasę podrzędną).
  • Przesłanianie metody zmienia zachowanie metody klasy pochodnej. Zwykle jest to bardziej szczegółowe, wyrafinowane zachowanie. Jeśli zastąpisz metodę w dziedzicu, która jest już w klasie nadrzędnej, w pewnym sensie zastąpi ona metodę nadrzędną.
  • Klasa może mieć tylko jedną klasę-przodka, ale każda klasa może mieć wiele „dzieci”.

Jak to działa

Łańcuch dziedziczenia jest kierowany od klasy najbardziej abstrakcyjnej do klasy bardziej konkretnej. Oznacza to, że nadklasa jest najbardziej abstrakcyjna w łańcuchu klas. Często jest oznaczana jako abstrakcyjna (klasa bazowa, która nie wymaga implementacji). Wszystkie dalsze zajęcia są bardziej szczegółowe. Na przykład istnieje klasa o nazwie „Gadżet”. Może mieć pole (lub stan) „masę” pojemności akumulatora pola, poziom naładowania pola oraz metody (lub zachowanie) „pracy” i ładowania. W tym przypadku metody mogą być abstrakcyjne, to znaczy nie mają konkretnej implementacji. Chociaż nie możemy powiedzieć, jaki to rodzaj gadżetu, jest to absolutnie każdy gadżet, który można ładować. Utwórzmy podklasę Phone klasy Gadget. Nie musi już na nowo definiować wagi i baterii, po prostu dziedziczy je z abstrakcyjnego gadżetu. Ale zachowanie pracy będzie musiało zostać wyjaśnione. Możesz także dodać inne pola „przekątna ekranu”, złącza i tak dalej. Możesz dodać nową metodę „Aktualizuj system operacyjny”. Następnie możemy utworzyć jeszcze dwie klasy i obie zostaną odziedziczone z Phone, Android i iPhone. Obie klasy dziedziczą wszystkie pola i metody gadżetu i smartfona, a metody można zastąpić. Pierwsza klasa potrzebuje pola „Nazwa marki”, natomiast iPhone nie potrzebuje tego pola, ponieważ tylko jedna firma produkuje takie smartfony.

class Gadget {}
}
//subclass of Gadget class
class Phone extends Gadget {}
//subclass of Phone class
class IPhone extends Phone {}
//subclass of Phone class
class AndroidPhone extends Phone {}
Klasa podrzędna dziedziczy wszystkie publiczne i chronione składowe klasy nadrzędnej. Nie ma znaczenia, w jakim pakiecie znajduje się podklasa. Jeśli klasa podrzędna znajduje się w tym samym pakiecie co klasa nadrzędna, dziedziczy również prywatne elementy pakietu rodzica. Możesz używać odziedziczonych członków w niezmienionej postaci, zastępować ich, ukrywać lub dodawać nowych członków:
  • Pola dziedziczone można używać bezpośrednio, tak jak wszelkich innych pól.
  • Możesz zadeklarować pole w klasie podrzędnej, które ma taką samą nazwę jak w klasie nadrzędnej. Ukrywa to (więc lepiej tego nie robić).
  • Możesz zadeklarować nowe pola w klasie podrzędnej (te, których nie ma w klasie nadrzędnej).
  • Metody dziedziczone mogą być używane bezpośrednio, bez przesłaniania w klasie pochodnej.
  • Możesz także napisać nową metodę instancji w podklasie, która będzie miała taki sam podpis jak metoda w klasie nadrzędnej. Ta procedura zastępuje to.
  • Możesz zadeklarować nowe metody w klasie podrzędnej, które nie zostały zadeklarowane w klasie nadrzędnej.
  • Można napisać konstruktor podklasy, który wywoła konstruktor nadklasy pośrednio lub za pomocą słowa kluczowego super.

Przykład

Stwórzmy podstawową klasę MusicalInstrument z polami wagi i znaku towarowego oraz metodą work() . Definiujemy również konstruktora.

public class MusicalInstrument {
   int weight;
   String tradeMark;

   public MusicalInstrument(int weight, String tradeMark) {
       this.weight = weight;
       this.tradeMark = tradeMark;
   }

   public void work() {
       System.out.println("the instrument is playing...");
   }
}
Nie jest całkowicie jasne, jaki to instrument muzyczny i jak na nim grać. Stwórzmy bardziej specyficzny instrument, skrzypce. Będzie miał takie same pola jak w Instrument muzyczny (zostaną wywołane w konstruktorze za pomocą słowa kluczowego super. Możemy też przesłonić metodę pracy i stworzyć metodę ustawiania struny skrzypiec po strunie.

public class Violin extends MusicalInstrument {
   String master;
   String owner;
   int age;
   boolean isTuned;

   public Violin(int weight, String tradeMark, String master, String owner, int age, boolean isTuned) {
       super(weight, tradeMark);
       this.master = master;
       this.owner = owner;
       this.age = age;
       this.isTuned = isTuned;
   }

   @Override
   public void work() {
       System.out.println("THe violin's playing");

   }

   public void violinTuning () {
     System.out.println("I'm tuning 1st string...");
     System.out.println("I'm tuning 2nd string...");
     System.out.println("I'm tuning 3rd string...");
     System.out.println("I'm tuning 4th string...");
}


}
Stwórzmy klasę Demo , aby przetestować klasę Violin i zobaczyć dokładnie, jak działa dziedziczenie.

public class InheritDemo {

   public static void main(String[] args) {

       Violin violin = new Violin(1, null, "Amati", "Kremer", 285, false);
       violin.violinTuning();
       violin.work();
   }
}
W tym przypadku wynik działania programu będzie następujący:
Stroję 1. strunę... Stroję 2. strunę... Stroję 3. strunę... Stroję 4. strunę... Skrzypce grają
Oznacza to, że jeśli w klasie potomnej znajduje się metoda przesłonięta, metoda przodka nie będzie już wywoływana. A co jeśli go tam nie ma? Oznacza to, że klasa Violin wygląda następująco:

public class Violin extends MusicalInstrument {
   String master;
   String owner;
   int age;
   boolean isTuned;

   public Violin(int weight, String tradeMark, String master, String owner, int age, boolean isTuned) {
       super(weight, tradeMark);
       this.master = master;
       this.owner = owner;
       this.age = age;
       this.isTuned = isTuned;
   }

  // @Override
 

 //  }

   public void violinTuning () {
       System.out.println("I'm tuning 1st string...");
       System.out.println("I'm tuning 2nd string...");
       System.out.println("I'm tuning 3rd string...");
       System.out.println("I'm tuning 4th string...");
   }

}
Dane wyjściowe to:
Stroję 1. strunę... Stroję 2. strunę... Stroję 3. strunę... Stroję 4. strunę... Instrument gra...
Oznacza to, że metoda przodka zostanie wywołana automatycznie. Nawiasem mówiąc, klasę potomną można zdefiniować poprzez przodka, czyli wykonać rzutowanie w górę:

Parent parent = new Child()
Ta inicjalizacja służy do uzyskania dostępu tylko do elementów obecnych w klasie nadrzędnej i do przesłoniętych metod. W naszym przykładzie byłoby to:

public class InheritDemo {

   public static void main(String[] args) {

       MusicalInstrument violin = new Violin(1, null, "Amati", "Kremer", 285, false);
       //violin.violinTuning();
       violin.work();
   }
}
W takim przypadku nie jesteśmy w stanie skonfigurować metody skrzypcowej. Jednak jednocześnie zostanie wywołana metoda work() klasy potomnej, jeśli taka istnieje.

Hierarchia klas platformy Java

W Javie wszystko składa się z klas i są one podporządkowane hierarchii. Powstaje pytanie: czy istnieje klasa, z której dziedziczone są wszystkie pozostałe? Odpowiedź brzmi: tak, rzeczywiście taka klasa istnieje. I nazywa się to po prostu Object . Klasa Object z pakietu java.lang definiuje i implementuje zachowanie wspólne dla wszystkich klas, łącznie z tymi, które tworzysz. Na platformie Java wiele klas wywodzi się bezpośrednio z obiektu Object , inne klasy wywodzą się z niektórych z tych klas itd., tworząc hierarchię klas.

Rodzaje dziedziczenia w Javie

Wyróżnijmy kilka typów dziedziczenia w Javie. 1. Dziedziczenie pojedyncze Ten typ działa podobnie jak w powyższym przykładzie, podklasy dziedziczą cechy jednej superklasy. Na poniższym obrazku klasa A służy jako klasa bazowa dla klasy pochodnej B. 2. Dziedziczenie wielopoziomowe To jest po prostu łańcuch dziedziczenia, czyli istnieje klasa bazowa A, klasa B jest z niej dziedziczona, a klasa C jest dziedziczona z klasy B. W Javie klasa nie może uzyskać bezpośredniego dostępu do elementów klasy nadrzędnej. 3. Dziedziczenie hierarchiczne W dziedziczeniu hierarchicznym jedna klasa służy jako nadklasa (klasa bazowa) dla więcej niż jednej podklasy. Powyżej podaliśmy przykład klasy Phone, która może mieć dwójkę „dzieci” — AndroidPhone i IPhone.

class A {
    public void printA() { 
System.out.println("A");
 }
}
  
class B extends A {
    public void printB() {
 System.out.println(" B"); }
}
  
class C extends A {
    public void printC() { 
System.out.println("C"); 
}
}
  
class D extends A {
    public void printD() { 
System.out.println("D");
 }
}
  
public class Demo {
    public static void main(String[] args)
    {
        B objB = new B();
        objB.printA();
        objB.printB();
  
        C objC = new C();
        objC.printA();
        objC.printC();
  
        D objD = new D();
        objD.printA();
        objD.printD();
    }
}
Dane wyjściowe to:
A B A C A D
4. Dziedziczenie wielokrotne, czyli obecność kilku przodków... ale czekaj, klasyczne dziedziczenie wielokrotne nie jest obsługiwane w Javie. W pewnym stopniu można to zaimplementować nie przy użyciu klas, ale interfejsów.

interface A {
   public void printA();
}

interface B {
   public void printB();
}

interface C extends A, B {
   public void print();
}
class InheritDemo implements C {
   @Override
   public void print()
   {
       System.out.println("Print something");
   }
  
   @Override
   public void printA() {      
   }

   @Override
   public void printB() {
   }
}
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION