OBJEKTINIS PROGRAMAVIMAS
Java paveldėjimas
Paveldėjimas leidžia naujai klasei perimti kitos klasės laukus ir metodus. Taip bendras kodas laikomas bazinėje klasėje, o specializuotos klasės jį papildo arba pritaiko.
Superclass ir subclass
| Sąvoka | Lietuviškai | Paskirtis |
|---|---|---|
| Superclass | Bazinė arba tėvinė klasė | Klasė, kurios nariai paveldimi |
| Subclass | Išvestinė arba vaikinė klasė | Klasė, kuri paveldi ir papildo bazinę klasę |
Java klasė kitą klasę paveldi naudodama raktažodį extends.
Paveldėjimas su extends
Paprastas kasdienis pavyzdys: knyga yra viena iš leidinio rūšių, todėl klasė Knyga gali paveldėti klasę Leidinys.
class Leidinys {
protected String pavadinimas = "Mažasis princas";
public void rodytiPavadinima() {
System.out.println("Leidinys: " + pavadinimas);
}
}
class Knyga extends Leidinys {
private int puslapiuSkaicius = 96;
public void rodytiPuslapius() {
System.out.println("Puslapių: " + puslapiuSkaicius);
}
public static void main(String[] args) {
Knyga knyga = new Knyga();
knyga.rodytiPavadinima();
knyga.rodytiPuslapius();
}
}Leidinys: Mažasis princas
Puslapių: 96
class Leidinysaprašo tai, ką turi visi leidiniai: pavadinimą ir jo parodymo metodą.class Knyga extends Leidinyspasako, kad knyga perima prieinamusLeidinysnarius.- Knyga papildomai turi savo lauką
puslapiuSkaiciusir metodąrodytiPuslapius(). - Sukurtas
Knygaobjektas gali iškviesti ir paveldėtą, ir savo metodą.
Paveldėtų narių naudojimas
class Leidinys {
protected String kategorija = "Vaikų literatūra";
public void rodytiKategorija() {
System.out.println("Kategorija: " + kategorija);
}
}
class Knyga extends Leidinys {
public void rodytiInformacija() {
rodytiKategorija();
System.out.println("Kategorijos pavadinime yra "
+ kategorija.length() + " simbolių.");
}
public static void main(String[] args) {
Knyga knyga = new Knyga();
knyga.rodytiInformacija();
}
}Kategorija: Vaikų literatūra
Kategorijos pavadinime yra 16 simbolių.
Knygapaveldiprotectedlaukąkategorijair viešą metodąrodytiKategorija().- Metodas
rodytiInformacija()pirmiausia iškviečia paveldėtą metodą. - Tada jis tiesiogiai panaudoja paveldėtą
protectedlauką ir suskaičiuoja teksto simbolius.
private nariai tiesiogiai poklasiui nepasiekiami.Bazinė klasė gali juos apsaugoti ir suteikti kontroliuojamą prieigą per protected arba viešus metodus.
Bazinės klasės konstruktorius
super(...) iškviečia bazinės klasės konstruktorių ir turi būti pirmoji poklasio konstruktoriaus instrukcija:
class Leidinys {
protected String pavadinimas;
Leidinys(String pavadinimas) {
this.pavadinimas = pavadinimas;
}
}
class Knyga extends Leidinys {
private int puslapiuSkaicius;
Knyga(String pavadinimas, int puslapiuSkaicius) {
super(pavadinimas);
this.puslapiuSkaicius = puslapiuSkaicius;
}
public void rodytiInformacija() {
System.out.println(pavadinimas + ": "
+ puslapiuSkaicius + " puslapiai");
}
public static void main(String[] args) {
Knyga knyga = new Knyga("Mažasis princas", 96);
knyga.rodytiInformacija();
}
}Mažasis princas: 96 puslapiai
- Kuriant
Knygaobjektą konstruktorius gauna pavadinimą ir puslapių skaičių. super(pavadinimas)perduoda pavadinimą bazinės klasėsLeidinyskonstruktoriui.- Bazinė klasė išsaugo bendrą pavadinimą, o
Knygaišsaugo tik jai reikalingą puslapių skaičių.
Paveldėto metodo perrašymas
Poklasis gali pateikti savo paveldėto metodo realizaciją:
class Leidinys {
public void rodytiTipa() {
System.out.println("Tai yra leidinys");
}
}
class Knyga extends Leidinys {
@Override
public void rodytiTipa() {
System.out.println("Tai yra knyga");
}
public static void main(String[] args) {
Leidinys leidinys = new Leidinys();
Knyga knyga = new Knyga();
leidinys.rodytiTipa();
knyga.rodytiTipa();
}
}Tai yra leidinys
Tai yra knyga
Leidinyspateikia bendrą metodorodytiTipa()elgesį.Knygapaveldi šį metodą, tačiau jį perrašo savo versija.@Overridepadeda kompiliatoriui patikrinti, ar toks metodas tikrai yra bazinėje klasėje.- Todėl tas pats metodo pavadinimas skirtingiems objektams gali pateikti skirtingą rezultatą.
Kada naudoti paveldėjimą?
- Kai poklasis iš tiesų yra konkretesnė bazinės klasės rūšis.
- Kai kelios klasės dalijasi bendra būsena ir elgsena.
- Kai bendras kodas gali būti prižiūrimas vienoje bazinėje klasėje.
- Kai paveldėtas elgesys turi būti specializuojamas perrašant metodus.
Paveldėjimas neturėtų būti naudojamas vien tam, kad būtų pasiektas svetimas kodas. Jei objektai nėra natūraliai susiję ryšiu „yra“, dažnai tinkamesnė kompozicija – vieno objekto laikymas kito objekto lauke.
Paveldėjimo ribojimas su final
final klasė negali turėti poklasių:
final class BibliotekosKortele {
}
// Klaida: final klasės paveldėti negalima
class SpecialiKortele extends BibliotekosKortele {
}error: cannot inherit from final BibliotekosKortele
BibliotekosKortele pažymėta final, todėl Java neleidžia sukurti ją paveldinčios klasės.
final taip pat gali uždrausti konkretaus metodo perrašymą:
class Leidinys {
public final void rodytiIsbn() {
System.out.println("ISBN: 978-609-00-0000-0");
}
}
class Knyga extends Leidinys {
@Override
// Klaida: final metodo perrašyti negalima
public void rodytiIsbn() {
}
}error: rodytiIsbn() in Knyga cannot override rodytiIsbn() in Leidinys
overridden method is final
Poklasis paveldi final metodą ir gali jį naudoti, tačiau negali pakeisti jo veikimo.
Svarbios Java paveldėjimo taisyklės
- Klasė tiesiogiai gali paveldėti tik vieną kitą klasę.
- Visos klasės tiesiogiai arba netiesiogiai paveldi
Object. - Konstruktoriai nepaveldimi, tačiau poklasio konstruktorius iškviečia bazinės klasės konstruktorių.
privatenariai nėra tiesiogiai pasiekiami poklasyje.- Poklasis gali pridėti savo laukus ir metodus bei perrašyti leidžiamus metodus.

