25
Visoka tehni č ka škola Niš Internet programiranje (7) Nasleđivanje klasa u Javi Prof. dr Zoran Veličković, dipl. inž. el. Novembar, 2017. Studijski program: Savremene ra č unarske tehnologije

Visoka tehnička škola Niš - vtsnis.edu.rsvtsnis.edu.rs/wp-content/plugins/vts-predmeti/uploads/7... · ,jsu promenjljive klase A. ... Da bi se sprečile greškekoje bi prijavio

  • Upload
    vanhanh

  • View
    218

  • Download
    1

Embed Size (px)

Citation preview

Visoka tehnička škola Niš

Internet programiranje(7)

Nasleđivanje klasa u JaviProf. dr Zoran Veličković, dipl. inž. el.

Novembar, 2017.

Studijski program:Savremene računarske tehnologije

NASLEĐIVANJE KLASA je kamen temeljac OO programiranja.

NASLEĐIVANJE KLASA podrazumeva formiranje OPŠTE KLASE kojom se definišu ZAJEDNIČKE KARAKTERISTIKE skupa srodnih pojava.

Ovako formiranu OPŠTU KLASU mogu da NASLEDE SPECIFIČNE KLASEkoje kroz nasleđivanje pridodaju SVOJE SPECIFIČNOSTI opštoj klasi.

Nasleđena klasa se naziva NATKLASA (engl. superclass).

Klasa koja nasleđuje naziva se POTKLASA (engl. subclass).

Takođe, može da se kaže da je potklasa specifičan slučaj natklase.

Nasleđivanje se u Javi implementira rezervisanom reči extends:

class ime_potklase extends ime_natklase {

//telo klase

}

Nasleđivanje klasa

Rezervisana reč extends za nasleđivanje klasa

Nasleđivanje klase OblikOPŠTA KLASA, natklasa

SPECIFIČNE klasepotklase/natklase

Oblik

Dvodimenziomi oblik Trodimenzioni oblik

KvadratKrug Trougao Sfera Kocka Tetraedar

Ako metoda POTKLASE ima ISTO IME kao i metoda NATKLASE, onda se ona REDEFINIŠE (engl. override).

Kada se UNUTAR POTKLASE pozove REDEFINISANA METODA izvršiće se verzija definisana u POTKLASI!

Dakle, verzija metode u NATKLASI biće SAKRIVENA.

REDEFINISANJE METODE je moguće SAMO ako su IMENA i TIPOVImetoda IDENTIČNI.

Međutim, ako imena i tipovi promeljivih u metodi NISU IDENTIČNI, onda su metode PREKLOPLJENE (engl. overlapped).

REDEFINISANJE METODA omogućava da OPŠTA KLASA definiše metode koje će biti ZAJEDNIČKE ZA SVE KLASE, ostavljajući potklasama slobodu da definišu SPECIFIČNE varijante NEKIH ili SVIH metoda.

Od čega zavisi koja od metoda će biti pozvana na izvršenje (originalna ili redefinisana)?

Redefinisanje i preklapanje metoda (1)

Ovaj problem se u OO programiranju naziva DINAMIČKO RAZREŠAVANJE METODA.

DINAMIČKO RAZREŠAVANJE METODA je Javin OO mehanizam pomoću koga se poziv upućen redefinisanoj metodi razrešava U TRENUTKU IZVRŠENJA (a ne kao što je to uobičajeno u proceduralnim jezicima -prilikom prevođenja - kompajliranja).

Ova RAZLIKA između procedurnih i OO jezika ima za posledicu da se u trenutku prevođenja NE ZNA koja će se metoda zapravo pozvati - o tome se odlučuje U TRENUTKU IZVŠAVANJA (ko to odlučuje?).

Ova važna karakteristika OO jezika omogućava da referencnaPROMENLJIVA NATKLASE može da ukaže na OBJEKAT POTKLASE.

Posledica ovog stava je da TIP REFERENCNOG OBJEKTA određuje KOJA ćemetoda biti pozvana, A NE TIP REFERENCNE PROMENLJIVE.

U procesu nasleđivanja, pored REDEFINISANJA i PREKLAPANJA metoda mogu se DODATI i NOVE metode i promenljive.

Dinamičko razrešavanje metoda

Nasleđivanje i dodavanje metoda (1)// Kreiranje klase A - biće kasnije korišćena kao natklasa

class A {int i, j;void prikaži_ij() {System.out.println("i i j: " + i + " " + j);}

}// Kreiranje potklase B nasleđivanjem natklase A

class B extends A {int k;void prikaži_k() {

System.out.println("k: " + k); }void zbir() {

System.out.println("i+j+k: " + (i+j+k)); } }

rezervisana reč: extends:klasa B nasleđuje klasu A

2 dodatne metodeklase B:

prikaži_k() i zbir()

U potklasi B nalaze se SVI ČLANOVI natklase A

k je promenljiva potklase B

i, j su promenjljive klase A

Nasleđivanje i dodavanje metoda (2)Kreiranje superOBJ - Objekt tipa A

subOBJ - Objekt tipa B

Potklasa ima pristupSVIM javnim

član. svoje natklase

class PrimerNasleđivanja {public static void main(String args[]) {A superOBJ = new A(); B subOBJ = new B();

// natklasa može da se koristi samostalno.

superOBJ.i = 10; superOBJ.j = 20;System.out.println(“Sadržaj natklase superOb: ");prikaži_ij();

System.out.println();/* potklasa ima pristup svim javnim članovima natklase*/

subOBJ.i = 7; subOBJ.j = 8; subOBJ.k = 9; System.out.println("Sadržaj objekta subOb: ");subOBJ.prikaži_ij(); subOBJ.prikaži_k();System.out.println();System.out.println("Suma i, j i k u subOb je :");subOBJ.zbir();

} }

i , j su vidljivi u objektima tipa A i B

POTKLASA sadrži SVE ČLANOVE svoje NATKLASE.

Međutim, POTKLASA ne može da pristupi onim članovima svoje natklase koji su označeni kao PRIVATNI.

ČLAN KLASE koji je deklerisan kao privatan, OSTAĆE PRIVATAN za svoju klasu i NEĆE BITI DOSTUPAN izvan te klase – čak ni iz POTKLASE.

U Javi potklasa može imati SAMO JEDNU natklasu!

U procesu višestrukog nasleđivanja POTKLASA MOŽE POSTATI NATKLASAdrugoj potklasi.

Klasa NE MOŽE biti SAMA SEBI NATKLASA!

Uticaj paketa i identifikatora pristupa na pristup članovima klasa dat je u sledećoj tabeli.

U nastavku biće prikazan primer koji se NE MOŽE KOMPAJLIRATI zbog greške koja se odnosi na parvo pristupa privatnoj promenljivoj u potklasi.

Kontrola pristupa i nasleđivanje (1)

Paketi i pristup članovima klaseSPECIFIKATOR

PRISTUPA private bez spec. protected public

Ista klasa Da Da Da Da

Potklasa istog paketa Ne Da Da Da

Klasa istog pak.koje nisu potkl. Ne Da Da Da

Potklase iz drugog paketa Ne Ne Da Da

Klase iz drugih paketa koje nisu

potklaseNe Ne Ne Da

Kontrola pristupa i nasleđivanje (1)

Paket 1Paket 2

Nasleđuje se

Nasleđuje se

Nasleđuje se

Nasleđuje se

Nasleđuje se

Kontrola pristupa i nasleđivanje (2)

Nasleđuje se

Objekt izvedene klase-postoje svi članovi bazne

klase, ali nekima se ne može pristupiti iz metoda

izvedene klaseČlanovi potklasnog objekta

Nedostupni bazni članovi

Kontrola pristupa i nasleđivanje (3)class A {int i; private int j;void setij(int x, int y) {i = x;j = y;

}}

class B extends A {int total;void sum() {total = i + j; // GREŠKA, program se ne može kompajlirati!

}}

Natklasa A

Promenljiva j NIJE DOSTUPNA ovde jer je privatna promeljiva clase A !!

Podrazumeva se javni pristup

Privatno za klasu A

Potklasa B

Kontrola pristupa i nasleđivanje (4)class Access {

public static void main(String args[])

{

B subOBJ = new B();

subOb.setij(10, 12);

subOBJ.sum();

System.out.println("Total is " + subOb.total);

}

}Ovaj program nije moguće kompajlirati !!

Referencnoj promenljivoj NATKLASE može se dodeliti referenca na bilo kojupotklasu izvedenu iz te natklase.

Za određivanje kojim se članovima može pristupiti bitan je TIP REFERENCNE PROMENLJIVE, a NE TIP OBJEKTA na koji ona ukazuje.

Kada se referenca na OBJEKT POTKLASE dodeli referencnoj promenljivoj NATKLASE, imaće pristup SAMO ONIM DELOVIMA OBJEKTA koji su definisani NATKLASOM.

Ovo je logično, jer NATKLASA NE ZNA šta je sve dodato u potklasi kroz proces nasleđivanja!

Pogledamo primer na sledećem slajdu.

Pretpostavlja se da je klasa Box NATKLASA klase BoxWeight.

Natklasa referencira obj. potklase (1)

Box BoxWeight

Natklasa referencira obj. potklase (2)class RefDemo {public static void main(String args[]) {BoxWeight weightbox = new BoxWeight(3, 5, 7, 8.37);Box plainbox = new Box();double vol;vol = weightbox.volume();System.out.println("Volume of weightbox is " + vol);System.out.println("Weight of weightbox is " + weightbox.weight);System.out.println();plainbox = weightbox;

vol = plainbox.volume(); // OK, volume() je definisano u klasi Box

System.out.println("Volume of plainbox is " + vol);// System.out.println("Weight of plainbox is " + plainbox.weight);}

}

Dodeljivanje vrednosti referencne promenljive objekta BoxWeight referencnoj promenljivoj

objekta Box (ovo je DOZVOLJENO)

GREŠKA, plain nema član weight!

weightbox je objekt klase BoxWeight (poseduje metodu volume) koja je izvedena iz klase Box

Na prethodnom primeru je pokazano kako PROMENLJIVA NATKLASE možeda referencira OBJEKT POTKLASE.

Međutim, kad POTKLASA treba da se obrati svojoj neposrednoj NATKLASIto se može uraditi rezervisanom reči super.

Rezervisana reč super ima dva pojavna oblika:

1. Poziva konstruktor natklase ili

2. Pristupa članu natklase koji je bio sakriven članom poklase.

POTKLASA može da pozove konstruktor definisan natklasom koristeći naredbu super na sledeći način:

super (lista parametara)

Naredba super mora da bude PRVA NAREDBA koja se izvršava unutar konstruktora potklase.

Rezervisana reč: super (1)

class Box {double width;double height;double depth;...// različiti konstruktori sa parametrima i/ili bez njih

...}

class BoxWeight extends Box {double weight;BoxWeight(double w, double h, double d, double m) {super(w,h,d)

weight = m; }

Rezervisana reč: super (2)

Klasa Box se proširuje da uključi težinu: BoxWeight

1. konstruktor za BoxWeightkoji inicijalizuje promenljive

Poziv (inicijalizacija) konstruktora NATKLASE Box

BoxWeight(BoxWeight ob) {super(ob)

weight = ob.weight; }

BoxWeight() {super()

weight = -1; }

}

Rezervisana reč: super (2)

Prosleđivanje objektakonstruktoru

3. Podrazumevani konstruktorza BoxWeight

Napomena: Nisu prikazani konstruktori kojeposeduje klasa Box, a na koje se poziva klasa BoxWeight

2. konstruktor za BoxWeight

Pozivi konstruktora NATKLASE Box

Primer: klase Kutija sa težinomclass DemoBoxWeight {public static void main(String args[]) {BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3);BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076);double vol;vol = mybox1.volume();System.out.println("Volume of mybox1 is " + vol);System.out.println("Weight of mybox1 is " + mybox1.weight);System.out.println();vol = mybox2.volume();System.out.println("Volume of mybox2 is " + vol);System.out.println("Weight of mybox2 is " + mybox2.weight);

}}

Poznaje ovaj podatak

Drugi način primene reči super Drugi oblik upotrebe rezervisane reči super je sličan upotrebi reči

this.

Rezervisana reč super uvek ukazuje na NATKLASU POTKLASE u kojoj je upotrebljena!

Ovaj oblik se primenjuje na sledeći način: super.član

class A { int i; }class B extend A {

int i;B(int a, int b) {super.i=a;i=b;

}...

skriva i iz klase A

i iz klase B

konstruktor klase Bi iz klase A

Apstraktne metode i klase (1) Može se definisati NATKLASA koja samo DEKLARIŠE STRUKTURU KLASE

BEZ DETALJNOG DEFINISANJA SVIH METODA.

Ovako definisane metode nazivaju se APSTRAKTNE METODE.

Da bi se sprečile greške koje bi prijavio kompajler, ove metode se moraju označiti kao apstraktne ključnom rečju abstract.

Potklase apstraktne klase MORAJU REDEFINISATI SVE METODE.

Dekleracija apstraktne metode je sledeća:

abstract tip ime_metode (lista parametara);

Apstraktne metode NEMAJU TELO METODE!

Metode koje sadrže apstraktne klase I SAME SU APSTRAKTNE!

Apstraktne metode i klase (2)abstract class A {abstract void callme();

// Konkretne metode su dozvoljene u apstraktnim klasama

void callmetoo() {System.out.println("This is a concrete method.");

}}class B extends A {void callme() {System.out.println("B's implementation of callme.");

}}class AbstractDemo {public static void main(String args[]) {B b = new B(); b.callme(); b.callmetoo();

}}

Redefinisanje apstraktne metode callme()

apstraktna klasa A (sadrži aps.metodu)

Pri nasleđivanju MORA SE REDEFINISATI apstraktna metoda!

apstraktna metoda callme()

Višestepena hijerarhija Može se napraviti onoliko nivoa (slojeva) nasleđivanja koliko nam je potrebno!

Dakle, POTKLASA može biti NATKLASA neke druge klase!

Ako se imaju tri klase A, B i C, od kojih C može da bude potklasa klase B, a ova potklasa klase A!

Svaka potklasa nasleđuje SVE OSOBINE svojih natklasa!

Ponekad je potrebno SPREČITI NASLEĐIVANJE klasa.

To se obavlja modifikatorom final.

final class A {

// telo klase ...

}

Sprečavanje nasleđivanja klase A

class A {final void meth() {System.out.println(“Ovo je final metoda!.");

}}

class B extends A {void meth() { // Greška, ne može se redefinisati.

System.out.println(“Nelegalno!");}

}

Modifikator: final

Final metoda meth() se NE MOŽE redefinisati,

kompajler će prijaviti grešku

Korenska klasa Object SVE klase su potklase klase Object!

Klasa Object definiše sledeće metode:

Object clone() -- pravi novi object isti kao onaj koji se klonira

boolen equals(Object objekat) -- utvrđuje jednakost objekata

void finalize() -- poziv pre čišćenja nekorišćenog objekta.

class getClass() -- nalazi klasu objekta u trenutku izvršavanja.

int hashCode() -- vraća ključ za heš. pridružen objektu koji se poziva

void notify() -- nastavak izvrš. programske niti koja čeka pozivaoca

void notifyAll() -- nastavak izvrš. svih program. niti koje čekaju poziv

String toString() -- vraća znakovni niz koji opisuje objekt

void wait(long milisekunde) -- čeka izvršenje druge niti

void wait(long milisekunde, int nanosekunde) -- isto