Vodič za nasljeđivanje na Javi

1. Pregled

Jedno od temeljnih načela objektno orijentiranog programiranja - nasljeđivanje - omogućuje nam ponovnu upotrebu postojećeg koda ili proširenje postojećeg tipa.

Jednostavno rečeno, u Javi klasa može naslijediti drugu klasu i više sučelja, dok sučelje može naslijediti druga sučelja.

U ovom ćemo članku započeti s potrebom za nasljeđivanjem, prelazeći na način na koji nasljeđivanje funkcionira s klasama i sučeljima.

Zatim ćemo pokriti kako imena varijabli / metode i modifikatori pristupa utječu na članove koji se nasljeđuju.

I na kraju ćemo vidjeti što znači nasljeđivati ​​tip.

2. Potreba za nasljeđivanjem

Zamislite da kao proizvođač automobila svojim kupcima nudite više modela automobila. Iako bi različiti modeli automobila mogli ponuditi različite značajke poput krovnog prozora ili neprobojnih prozora, svi bi oni imali zajedničke komponente i značajke, poput motora i kotača.

Ima smisla stvoriti osnovni dizajn i proširiti ga tako da stvori njihove specijalizirane verzije, nego dizajnirati svaki model automobila zasebno, od nule.

Na sličan način, s nasljeđivanjem, možemo stvoriti klasu s osnovnim značajkama i ponašanjem i stvoriti njene specijalizirane verzije, stvaranjem klasa koje nasljeđuju ovu osnovnu klasu. Na isti način, sučelja mogu proširiti postojeća sučelja.

Primijetit ćemo upotrebu više pojmova za upućivanje na vrstu koju nasljeđuje druga vrsta, posebno:

  • osnovni tip se također naziva super ili roditeljski tip
  • izvedeni tip naziva se prošireni, pod ili podređeni tip

3. Razredno nasljeđivanje

3.1. Proširenje razreda

Klasa može naslijediti drugu klasu i definirati dodatne članove.

Počnimo s definiranjem osnovne klase Automobil:

javna klasa Car {int kotači; Žičani model; void start () {// Provjeri bitne dijelove}}

Razred ArmoredCar može naslijediti članove Automobil razred po pomoću ključne riječi proteže se u svojoj deklaraciji:

javna klasa ArmoredCar proširuje Car {int bulletProofWindows; void remoteStartCar () {// ovo se vozilo može pokrenuti pomoću daljinskog upravljača}}

Sada možemo reći da je ArmoredCar razred je podrazred od Automobil, a potonji je superklasa od ArmoredCar.

Klase u Javi podržavaju jedno nasljeđivanje; the ArmoredCar klasa ne može proširiti više klasa.

Također imajte na umu da u nedostatku proteže se ključna riječ, klasa implicitno nasljeđuje klasu java.lang.Object.

Klasa potklase nasljeđuje nestatično zaštićen i javnost članovi iz razreda superrazreda. Uz to, članovi s zadano i paket pristup se nasljeđuje ako su dvije klase u istom paketu.

S druge strane, privatni i statički članovi klase nisu naslijeđeni.

3.2. Pristup roditeljskim članovima iz klase djeteta

Da bismo pristupili naslijeđenim svojstvima ili metodama, jednostavno ih možemo koristiti izravno:

javna klasa ArmoredCar proširuje Car {public String registerModel () {return model; }}

Imajte na umu da nam za pristup članovima nije potrebna referenca na superklasu.

4. Nasljeđivanje sučelja

4.1. Implementacija više sučelja

Iako klase mogu naslijediti samo jednu klasu, mogu implementirati više sučelja.

Zamislite ArmoredCar što smo definirali u prethodnom odjeljku potrebno je za super špijuna. Dakle Automobil proizvodna tvrtka mislila je dodati leteću i plutajuću funkcionalnost:

javno sučelje Floatable {void floatOnWater (); }
javno sučelje Flyable {void fly (); }
javna klasa ArmoredCar proširuje Oprema za automobile Floatable, Flyable {public void floatOnWater () {System.out.println ("Mogu plutati!"); } javna void fly () {System.out.println ("Mogu letjeti!"); }}

U gornjem primjeru primjećujemo upotrebu ključne riječi provodi naslijediti iz sučelja.

4.2. Problemi s višestrukim nasljeđivanjem

Java omogućuje višestruko nasljeđivanje pomoću sučelja.

Do Jave 7 to nije bio problem. Sučelja su mogla samo definirati sažetak metode, odnosno metode bez ikakve implementacije. Dakle, ako je klasa implementirala više sučelja s istim potpisom metode, to nije bio problem. Provedbena klasa na kraju je imala samo jednu metodu za implementaciju.

Pogledajmo kako se ta jednostavna jednadžba promijenila uvođenjem zadano metode u sučeljima, s Javom 8.

Počevši od Jave 8, sučelja mogu odabrati da definiraju zadane implementacije za svoje metode (sučelje još uvijek može definirati sažetak metode). To znači da ako klasa implementira više sučelja, koja definiraju metode s istim potpisom, podređena klasa nasljeđuje zasebne implementacije. Ovo zvuči složeno i nije dopušteno.

Java zabranjuje nasljeđivanje više implementacija istih metoda, definiranih u odvojenim sučeljima.

Evo primjera:

javno sučelje Plutajuće {zadana void popravak () {System.out.println ("Popravak plutajućeg objekta"); }}
javno sučelje Flyable {zadana void popravak () {System.out.println ("Popravak letećeg objekta"); }}
javna klasa ArmoredCar proširuje Oprema za automobile Plutajuće, Leteće {// ovo se neće sastaviti}

Ako želimo implementirati oba sučelja, morat ćemo nadjačati popravak() metoda.

Ako sučelja u prethodnim primjerima definiraju varijable s istim imenom, recimo trajanje, ne možemo im pristupiti bez prethodnog imena varijable s imenom sučelja:

javno sučelje Plutajuće {int duration = 10; }
javno sučelje Letljivo {int trajanje = 20; }
javna klasa ArmoredCar proširuje Oprema za automobile Plutajuće, leteće {public void aMethod () {System.out.println (trajanje); // neće kompajlirati System.out.println (Floatable.duration); // izlazi 10 System.out.println (Flyable.duration); // izlazi 20}}

4.3. Sučelja koja proširuju ostala sučelja

Sučelje može proširiti više sučelja. Evo primjera:

javno sučelje Floatable {void floatOnWater (); }
sučelje sučelja Leteći {void fly (); }
javno sučelje SpaceTraveller proširuje Floatable, Flyable {void remoteControl (); }

Sučelje nasljeđuje druga sučelja pomoću ključne riječi proteže se. Klase koriste ključnu riječ provodi za nasljeđivanje sučelja.

5. Nasljeđivanje tipa

Kada klasa naslijedi drugu klasu ili sučelja, osim nasljeđivanja svojih članova, ona nasljeđuje i njihov tip. To se također odnosi na sučelje koje nasljeđuje druga sučelja.

Ovo je vrlo moćan koncept koji omogućava programerima program na sučelje (osnovna klasa ili sučelje), umjesto programiranja za njihove implementacije.

Na primjer, zamislite stanje u kojem organizacija održava popis automobila u vlasništvu svojih zaposlenika. Naravno, svi zaposlenici možda posjeduju različite modele automobila. Pa kako se možemo pozvati na različite instance automobila? Evo rješenja:

zaposlenik u javnoj klasi {private String name; privatni automobil automobila; // standardni konstruktor}

Budući da su sve izvedene klase Automobil naslijediti tip Automobil, izvedene instance klase mogu se uputiti korištenjem varijable klase Automobil:

Zaposlenik e1 = novi zaposlenik ("Shreya", novi ArmoredCar ()); Zaposlenik e2 = novi zaposlenik ("Paul", novi SpaceCar ()); Zaposlenik e3 = novi zaposlenik ("Pavni", novi BMW ());

6. Skriveni članovi razreda

6.1. Članovi skrivene instance

Što se događa ako i superrazred i podrazred definiraju varijablu ili metodu s istim imenom? Ne brinite; još uvijek možemo pristupiti obojici. Međutim, svoju namjeru moramo jasno objasniti Javi dodavanjem varijable ili metode prefiksima s ključnim riječima ovaj ili super.

The ovaj ključna riječ odnosi se na instancu u kojoj se koristi. The super Ključna riječ (kako se čini očiglednom) odnosi se na instancu nadređene klase:

javna klasa ArmoredCar proširuje model Car {private String model; javni niz getAValue () {return super.model; // vraća vrijednost modela definiranog u osnovnoj klasi Car // // this.model; // vratit će vrijednost modela definiranog u ArmoredCar // vratiti model; // vratit će vrijednost modela definiranog u ArmoredCar}}

Puno programera koristi ovaj i super ključne riječi da bi eksplicitno naveli na koju se varijablu ili metodu pozivaju. Međutim, njihova upotreba sa svim članovima može učiniti naš kod pretrpanim.

6.2. Skriveni statični članovi

Što se događa kada naša osnovna klasa i potklase definiraju statičke varijable i metode s istim imenom? Možemo li pristupiti a statički član iz osnovne klase, u izvedenoj klasi, onako kako to radimo za varijable instance?

Otkrijmo na primjeru:

javna klasa Car {public static String msg () {return "Car"; }}
javna klasa ArmoredCar proširuje Car {public static String msg () {return super.msg (); // ovo se neće kompajlirati. }}

Ne, ne možemo. Statički članovi pripadaju klasi, a ne instancama. Dakle, ne možemo koristiti nestatično super ključna riječ u poruka ().

Budući da statički članovi pripadaju klasi, prethodni poziv možemo izmijeniti na sljedeći način:

povratak Car.msg ();

Razmotrimo sljedeći primjer, u kojem i osnovna klasa i izvedena klasa definiraju statičku metodu poruka () s istim potpisom:

javna klasa Car {public static String msg () {return "Car"; }}
javna klasa ArmoredCar proširuje Car {public static String msg () {return "ArmoredCar"; }}

Evo kako ih možemo nazvati:

Prvo auto = novi ArmoredCar (); ArmoredCar second = novi ArmoredCar ();

Za prethodni kod, first.msg () izlazit će „Auto i second.msg () će prikazati "ArmoredCar". Statička poruka koja se poziva ovisi o vrsti varijable na koju se poziva ArmoredCar primjer.

7. Zaključak

U ovom smo članku pokrili osnovni aspekt Java jezika - nasljeđivanje.

Vidjeli smo kako Java podržava jedno nasljeđivanje s klasama i višestruko nasljeđivanje sa sučeljima i razgovarali o zamršenosti načina na koji mehanizam radi u jeziku.

Kao i uvijek, puni izvorni kod za primjere dostupan je na GitHubu.


$config[zx-auto] not found$config[zx-overlay] not found