Moştenire
Moștenirea Java se referă la capacitatea unei clase Java de a inherit
proprietățile din alte clase. Gândiți-vă la el ca la un copil care moștenește proprietăți de la părinți, conceptul este foarte asemănător cu acela. În lingo Java, se mai numește extinde-Citarea unei clase.
Câteva lucruri simple de reținut:
- Clasa care se extinde sau moștenește se numește a subclasă
- Clasa care este extinsă sau moștenită se numește a superclasa
Astfel, moștenirea oferă Java capacitatea de a refolosirea cod sau partajarea codului între clase!
Să-l descriem cu exemplul clasic al unui Vehicle
clasa și a Car
clasa:
public class Vehicle {
public void start() {
// starting the engine
}
public void stop() {
// stopping the engine
}
}
public class Car extends Vehicle {
int numberOfSeats = 4;
public int getNumberOfSeats() {
return numberOfSeats;
}
}
Aici, putem vedea Car
clasă care moștenește proprietățile Vehicle
clasă. Deci, nu trebuie să scriem același cod pentru metode start()
și stop()
pentru Car
de asemenea, deoarece acele proprietăți sunt disponibile de la părintele sau superclasa sa. Prin urmare, obiectele create din Car
clasa va de asemenea au acele proprietăți!
Car tesla = new Car();
tesla.start();
tesla.stop();
Dar, clasa părinte are metodele copilului? Nu, nu.
Prin urmare, ori de câte ori trebuie să partajați o bucată de cod comună între mai multe clase, este întotdeauna bine să aveți o clasă părinte și apoi extindeți acea clasă ori de câte ori este necesar! Reduce numărul de linii de cod, face codul modular și simplifică testarea.
Ce se poate moșteni?
- Toate
protected
șipublic
câmpuri și metode de la părinte
Ce nu poate fi moștenit?
-
private
câmpuri și metode - Constructori. Deși, constructorul subclasei are pentru a apela constructorul superclasei dacă este definit (Mai multe despre asta mai târziu!)
- Clase multiple. Java acceptă numai moștenire unică, adică nu poți moșteni decât o singură clasă la un moment dat.
- Câmpuri. Câmpurile individuale ale unei clase nu pot fi suprascrise de subclasă.
Tastați Distribuție și referință
În Java, este posibil să se facă referire la o subclasă ca la instanță a superclasei sale. Se numeste Polimorfism în programarea orientată pe obiecte (OOP), capacitatea unui obiect de a lua mai multe forme. De exemplu, Car
obiectul clasei poate fi referit ca un Vehicle
instanță de clasă ca aceasta:
Vehicle car = new Car();
Deși, opusul nu este posibil:
Car car = new Vehicle(); // ERROR
Deoarece puteți face referire la o subclasă Java ca instanță de superclasă, puteți arunca cu ușurință o instanță a unui obiect de subclasă într-o instanță de superclasă. Este posibil să aruncați un obiect de superclasă într-un tip de subclasă, dar numai dacă obiectul este într-adevăr o instanță a subclasei. Așa că rețineți acest lucru:
Car car = new Car();
Vehicle vehicle = car; // upcasting
Car car2 = (Car)vechile; //downcasting
Bike bike = new Bike(); // say Bike is also a subclass of Vehicle
Vehicle v = bike; // upcasting, no problem here.
Car car3 = (Car)bike; // Compilation Error : as bike is NOT a instance of Car
Acum știți cum să partajați codul printr-o relație părinte-copil. Dar, dacă nu vă place implementarea unei anumite metode în clasa de copii și doriți să scrieți una nouă pentru aceasta? Ce faci atunci?
Înlocuiți-l!
Java vă permite trece peste sau redefiniți metodele definite în superclasă. De exemplu, dvs. Car
clasa are o implementare diferită de start()
decât părintele Vehicle
, deci faceți acest lucru:
public class Vehicle {
public void start() {
System.out.println("Vehicle start code");
}
}
public class Car extends Vehicle {
public void start() {
System.out.println("Car start code");
}
}
Car car = new Car();
car.start(); // "Car start code"
Deci, este destul de simplu să înlocuiți metodele din subclasă. Deși există un captură. Doar acea metodă superclass cu semnătură exact aceeași metodă deoarece metoda subclasei va fi suprascrisă. Aceasta înseamnă că definiția metodei subclaselor trebuie să aibă exact același nume, același număr și tip de parametri și în aceeași succesiune exactă. Prin urmare, public void start(String key)
nu ar suprascrie public void start()
.
Note :
- Nu puteți suprascrie metodele private ale superclasei. (Destul de evident, nu-i așa?)
- Ce se întâmplă dacă metoda superclasei pe care o suprascrieți în subclasă devine brusc anulată sau metodele schimbate? Ar eșua în timpul rulării! Deci, Java vă oferă o adnotare inteligentă
@Override
pe care îl puteți plasa peste metoda subclasei, care va avertiza compilatorul cu privire la aceste incidente!
Adnotările în Java sunt o bună practică de codare, dar nu sunt o necesitate. Compilatorul este suficient de inteligent pentru a-și da seama că suprasolicită singur. Spre deosebire de alte limbaje OOP, Adnotările în Java nu modifică neapărat metoda sau adaugă funcționalitate suplimentară.
Cum să apelați metodele super clasei?
Amuzant că întrebi despre asta! Folosiți doar cuvântul cheie super
:
public class Vehicle() {
public void start() {
System.out.println("Vehicle start code");
}
}
public class Car extends Vehicle {
public void run() {
super.start();
}
}
Car car = new Car();
car.run(); // "Vehicle start code"
NB : Deși puteți apela metoda părinte folosind un super
apel, nu puteți urca ierarhia moștenirii cu lanțuri super
apeluri.
Cum se știe tipul unei clase?
Folosind instanceof
cuvânt cheie. Având o mulțime de clase și subclase, ar fi puțin confuz să știm care clasă este o subclasă dintre care una în timpul rulării. Deci, putem folosi instanceof
pentru a determina dacă un obiect este o instanță a unei clase, o instanță a unei subclase sau o instanță a unei interfețe.
Car car = new Car();
boolean flag = car instanceof Vehicle; // true in this case!
Constructori și moștenire
După cum sa menționat mai devreme, constructorii nu pot fi moșteniți direct de o subclasă. Deși, o subclasă este necesar să numească constructorul părintelui său ca fiind prima operație în propriul său constructor. Cum? Ai ghicit, folosind super
:
public class Vehicle {
public Vehicle() {
// constructor
}
public void start() {
System.out.println("Vehicle start code");
}
}
public class Car extends Vehicle {
public Car() {
super();
}
public void run() {
super.start();
}
}
Amintiți-vă, dacă superclasa nu are niciun constructor definit, nu trebuie să o apelați explicit în subclasă. Java se ocupă de asta intern pentru tine! Invocare la super
constructorul se face în cazul în care super clasa urmează să fie apelată cu orice alt constructor în afară de constructor implicit.
Dacă nu sunt definiți alți constructori, atunci Java invocă constructorul implicit de super clasă (chiar dacă nu este definit explicit).
Felicitări, acum știi totul despre Moștenire! Citiți mai multe despre modalitățile avansate de a moșteni lucrurile în Clasele abstracte și Interfețe!