150 likes | 377 Views
Java – Mostenire si polimorfism. Interfete si polimorfism concepte declarare, creare, utilizare supraincarcare si polimorfism Mostenire descriere ierarhii. Interfete - concepte. una dintre problemele de baza in Java este reutilizarea codului in cat mai multe proiecte;
E N D
Java – Mostenire si polimorfism Interfete si polimorfism concepte declarare, creare, utilizare supraincarcare si polimorfism Mostenire descriere ierarhii
Interfete - concepte • una dintre problemele de baza in Java este reutilizarea codului in cat mai multe proiecte; • reutilizarea codului este deseori posibila numai dupa realizarea unor mici ajustari; • o strategie de scriere a codului consta in separarea portiunilor reutilizabile in interfete, de cele ce sunt dependente de implementare; • pentru a produce o aplicatie noua interfata se pastreaza insa acesteia i se ataseaza o noua clasa cu metodele de prelucare specifice noului de context de lucru; • comportamentul codului variaza in functie de clasa care a fost atasata, fenomemul purand denumirea de polimorfism.
Interfete – declarare, creare si utilizare Se pune problema realizarii unei aplicatii pentru prelucrarea unor obiecte grafice din categoria: punct, cerc, patrat, dreptunghi … Toate aceste obiecte grafice au caracteristici comune din categoria perimetru, arie, volum, insa formulele de calcul concrete difera de la caz la caz. O modalitate de implementare cu reutuilizare de cod se prezinta in continuare. 1. Se declara o interfata ce sa contina toate metodele comune ale obiectelor 2. Se creeaza clasele ce implementeaza concret codurile (vezi slide-ul urmator) 3. Se testeaza clasele create. public interface InterfataGeometrica { double Perimetru(); double Arie(); double Volum(); String Nume(); } public class Test { public static void main(String[] args) { Punct p = new Punct("\nPunct", 2.,3.); Cerc c= new Cerc("\nCerc",p,10.); InterfataGeometrica ig; ig = p; System.out.println(ig.Nume()+"\nPerimetru: "+ig.Perimetru()+"\nArie: "+ig.Arie()); ig = c; System.out.println(ig.Nume()+"\nPerimetru: "+ig.Perimetru()+"\nArie: "+ig.Arie()); } }
Interfete – declarare, creare si utilizare Noile clase cu implements trebuie sa defineasca metodele din interfata. public class Cerc implements InterfataGeometrica { String nume; Punct centru; double raza; public Cerc(String nume, Punct p, double r) { this.nume=nume; centru=p; raza= r; } public String Nume() { return nume; } public double Perimetru() { return 2.*Math.PI*raza; } public double Arie() { return Math.PI*raza*raza; } public double Volum() { return 0.; } } public class Punct implements InterfataGeometrica{ String nume; double x, y; public Punct(String nume, double x, double y) { this.nume=nume; this.x=x; this.y=y; } public String Nume() { return nume; } public double Perimetru() { return 0.; } public double Arie() { return 0.; } public double Volum() { return 0.; } }
Polimorfism • cand mai multe clase implementeaza aceeasi interfata, fiecare clasa implementeaza metodele in moduri diferite; • este legal sa avem o variabila de tipul interfata ca si in InterfataGeometrica ig caz in care variabila ig poate referi orice obiect ce implementeaza interfata respectiva; • polimorfismul face ca aceeasi metoda sa poate avea implementari distincte, adica codul se adapteaza la natura obiectului utilizat; • in cazul supraincarcarii metoda de apelat este selectata inainte de rularea codului in faza de traducere de catre compilator, in cazul polimorfismului metoda de apelat se alege in timpul compilarii programului de catre masina virtuala
Mostenire • un mecanism pentru extinderea unei clase prin adaugarea de noi metode sau variabile; • clasa mai generala se numeste superclasa, clasa mai specializata ce mosteneste de la superclasa se numeste subclasa; • in Java orice clasa extinde direct sau indirect clasa Object; • mostenirea difera de implementarea unei interfete (interfata nu este o clasa, nu are stare sau comportament), subclasa mosteneste metodele si variabilele superclasei; din acest motiv efortul pentru scrierea superclasei se preia in subclasa; • la definirea subclasei se pot realiza urmatoarele: • adaugarea de variabile de instanta; • adaugarea de metode; • modificarea sau extinderea unei metode deja existente.
Aplicatia 1 / 1 Dorim sa scriem o aplicatie care sa foloseasca obiecte punct si coordonata, cel din urma fiind o subclasa a primei clase. Iata implementarea: public class Coordonate { private double x; private double y; Coordonate(){ setX(0); setY(0); } Coordonate(double x, double y){ setX(x); setY(y); } public void setX(double x) { this.x = x; } public double getX() { return x; } public double getY() { return y; } public void setY(double y) { this.y = y; } public String toString() { return "(" + x + "," + y + ")"; } } public class Punct extends Coordonate { private String nume; public Punct() { super(); setNume("P"); } public Punct(double x, double y) { super(x,y); setNume("P"); } public Punct(double x, double y, String nume) { this(x,y); setNume(nume); } public Punct(Coordonate c, String nume) { this(c.getX(),c.getY()); setNume(nume); } public void setNume(String nume){ this.nume = nume; } public String toString() { return nume + super.toString(); } }
Aplicatia 1 / 2 • subclasa nu are acces la membrii privati din superclasa; • cuvantul cheie super se foloseste pentru apelarea unei metode din superclasa; • orice referinta la subclasa se poate converti la o referinta la superclasa; • apelul de metode este determinat de tipul actual al obiectului nu de catre tipul referintei la obiect. public class Mostenire { public static void main(String[] args) { Coordonate c1 = new Coordonate(); Coordonate c2 = new Coordonate(1,2); Punct p1 = new Punct(); Punct p2 = new Punct(1,1); Punct p3 = new Punct(1,2,"P3"); Punct p4 = new Punct(c1,"P4"); System.out.println(c1); System.out.println(c2); System.out.println(p1); System.out.println(p2); System.out.println(p3); System.out.println(p4); c1 = p1; //subclasa = superclasa System.out.println(c1); c1 = c2; System.out.println(c1); //p1 = (Punct)c1; //aici primim eroare //invers nu se poate! } }
Ierarhii de clase • conceptele folosite pentru a scrie o aplicatie pot forma ierarhii; • ierarhiile se reprezinta grafic sub forma arborescenta; conceptul cel mai general se afla la baza (sau radacina) in timp ce cele specializate reprezinta frunzele; Implementati o aplicatie cu ierarhia alaturata si ale caror clase si metode se implementeaza conform tabelului urmator:
Aplicatia 2/1 public class Punct extends Forma { private int x; private int y; public Punct() { // apel implicit constructor Object } public Punct( int xValue, int yValue ) { // aici apel implicita constructor Object x = xValue; y = yValue; } public void setX( int xValue ){ x = xValue; } public int getX() { return x; } public void setY( int yValue ) { y = yValue; } public int getY() { return y; } public String getNume(){ return "Punct "; } public String toString() { return "(" + getX() + ", " + getY() + ")"; } } public class Forma { public double getArie() { return 0.0; } public double getVolum() { return 0.0; } public String getNume() { return null; } }
Aplicatia 2/2 public class Cerc extends Punct { private double raza; public Cerc(){ // apel constructor implicit } public Cerc( int x, int y, double valoareRaza ){ super( x, y ); // apel constructor Punct setRaza( valoareRaza ); } public void setRaza( double valoareRaza ){ raza = ( valoareRaza < 0.0 ? 0.0 : valoareRaza ); } public double getRaza(){ return raza; } public double getDiametru() { return 2. * getRaza(); } public double getPerimetru() { return Math.PI * getDiametru(); } public double getArie(){ return Math.PI * getRaza() * getRaza(); } public String getNume() { return "Cerc "; } public String toString(){ return "Centru = " + super.toString() + "; Raza = " + getRaza(); } }
Aplicatia 2/3 public class Cilindru extends Cerc { private double inaltime; public Cilindru(){ } public Cilindru( int x, int y, double raza, double h){ super( x, y, raza ); setInaltime( h ); } public void setInaltime( double valoareInaltime ){ inaltime = ( valoareInaltime < 0.0 ? 0.0 : valoareInaltime ); } public double getInaltime(){ return inaltime; } public double getArie() { return 2 * super.getArie() + getPerimetru() * getInaltime(); } public double getVolum(){ return super.getArie() * getInaltime(); } public String getNume(){ return "Cilindru"; } public String toString(){ return super.toString() + "; Height = " + getInaltime(); } }
Aplicatia 2/4 import java.text.DecimalFormat; import javax.swing.JOptionPane; public class TestMostenire { public static void main( String args[] ) { DecimalFormat douaZecimale = new DecimalFormat( "0.00" ); Punct punct = new Punct( 1, 7 ); Cerc cerc = new Cerc( 21, 7, 2.5 ); Cilindru cilindru = new Cilindru( 21, 30, 3.5, 11.5 ); String output = punct.getNume() + ": " + punct + "\n" + cerc.getNume() + ": " + cerc + "\n" + cilindru.getNume() + ": " + cilindru + "\n"; Forma tablouDeForme[] = new Forma[ 3 ]; // creare tablou Forme tablouDeForme[ 0 ] = punct; tablouDeForme[ 1 ] = cerc; tablouDeForme[ 2 ] = cilindru; for ( int i = 0; i < tablouDeForme.length; i++ ) { output += "\n\n" + tablouDeForme[ i ].getNume() + ": " + tablouDeForme[ i ].toString() + "\nArea = " + douaZecimale.format( tablouDeForme[ i ].getArie() ) + "\nVolume = " + douaZecimale.format( tablouDeForme[ i ].getVolum() ); } JOptionPane.showMessageDialog( null, output ); // display output System.exit( 0 ); } }
Bibliografie • http://www.east.utcluj.ro/mb/mep/antal/downloads.html > Java: course, IDE (JDeveloper), JDK and JRE, JDeveloper labs. • http://docs.oracle.com/cd/E18941_01/tutorials/jdtut_11r2_50/jdtut_11r2_50.html > Getting Started With the JDeveloper IDE