Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: http://upload.wikimedia.org/wikipedia/en/thumb/2/2e/Java_Logo.svg/322px-Java_Logo.svg.png   Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: http://hopf.chem.brandeis.edu/yanglingfa/pic/uml.GIF

 

 

 

     Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: Description: D:\_2010_Nokia\Curs Nokia-UPB 2011\ETTI_logo_bleu.jpg

Universitatea POLITEHNICA din Bucuresti

Facultatea de Electronica, Telecomunicatii si Tehnologia Informatiei

.

 

 

 

 

 

2011

 

 

 

Laboratorul  – sala B123

 

 

PSNIM

2012

Tehnologii de Programare

in Internet

(TPI)

 

21/02/2014

                     

   

 2013-2014

                                           

Laborator 1

Familiarizarea cu mediul de dezvoltare NetBeans 6.1 IDE.  Recapitularea Orientarii spre Obiecte (in limbajul Java)

1.1. Descrierea laboratorului

 

In aceasta lucrare de laborator vor fi acoperite urmatoarele probleme:

 

Utilizarea mediului de dezvoltare integrat NetBeans 6.1 IDE

 

Recapitularea Orientarii spre Obiect (Java)

            Crearea obiectelor si invocarea metodelor Java

            Tipuri de date Java si starea unui obiect

            Comportamentul unui obiect si interactiunea obiectelor

Semnaturile metodelor si returnarea valorilor (in Java), constructorii

            Supraincarcarea numelor metodelor si constructorilor – polimorfismul static

Asocierea intre clase

                        Mai multe detalii aici: http://discipline.elcom.pub.ro/POO-Java/

    http://discipline.elcom.pub.ro/POO-Java/Index%20of%20Laborator%20POO2007.htm

 

Studiu de caz (I):   Clasele DatePersonale, SituatieCurs si Student

 

Exercitii in laborator

 

Generalizarea si specializarea claselor

Mostenirea. Rescrierea codului (overriding)

Studiu de caz (II):   Clasele Persoana, Student, Profesor si StudentMaster

Anexe:

 

Instalarea kitului Java jdk-6u5-windows-i586-p.exe

Instalarea kitului NetBeans (DUPA instalarea kitului Java) netbeans-6.1-windows.exe

 

Atentie: La inceputul laboratoarelor stergeti mai intai toate proiectele existente (click dreapta pe

 nodul proiectului in fereastra Projects si selectati Delete, si confirmati ca doriti sa fie sterse

 surselein cazul proiectelor Java). La finalul laboratoarelor stergeti proiectele create.

 

 

1.2. Obiecte si clase (Java)

1.2.1. Definitii

 

Programele de calcul sunt secvente de instructiuni care prin executia lor pe sisteme (masini) de calcul rezolva probleme aparute in diferite domenii ale lumii reale. Programele sunt solutii ale acestor probleme. Un program scris intr-un limbaj orientat spre obiecte (OO) reprezinta un model al unei parti din lumea reala.

 

Elementele care compun modelul (numite OBIECTE software) sunt construite prin analogie cu entitati care apar in lumea reala (obiecte reale, concepte). Obiectele software obtinute prin modelare (analogie cu lumea reala) trebuie reprezentate in limbajul de programare.

 

Ca si in cazul obiectelor si conceptelor din lumea reala, obiectele software pot fi categorisite. O constructie software (structura complexa) numita CLASA descrie intr-o forma abstracta toate obiectele de un tip particular. La fel ca in lumea reala, in care obiectele si conceptele sunt clasificate pe baza atributelor esentiale pe care le au acestea, clasele reprezinta obiecte software care au atribute similare (atributele fiind elemente de date, variabile interne, proprietati care caracterizeaza obiectele).

 

Clasa defineste elementele comune, numite in Java CAMPURI (atribute in teoria orientarii spre obiecte) si METODE (operatii in teoria orientarii spre obiecte), ale unei categorii de obiecte. Clasa reprezinta astfel tipul de date al obiectelor.

OBIECTUL este un exemplu specific al unei clase, numit instanta a clasei, in care fiecare camp are o anumita valoare, iar CLASA este tiparul dupa care sunt construite obiectele.

 

Ansamblul valorilor campurilor (atributelor) unui obiect la un moment dat reprezinta STAREA obiectului.

Starea unui obiect poate diferi in timp, ca urmare a comportamentului. Starea a doua obiecte de acelasi tip poate fi diferita la un moment dat.

 

O metoda realizeaza o actiune asupra valorilor campurilor obiectului caruia ii apartine, putand folosi valorile acelor campuri, si astfel efectueaza o sarcina pentru codul (context) care a apelat-o.

Metoda este un atom de COMPORTAMENT al obiectului. Comportamentul global al obiectului este obtinut prin inlantuirea apelurilor de metode. Toate obiectele din aceeasi clasa au aceleasi metode disponibile.

 

Metoda Java (operatia in teoria OO), atunci cand este executata, realizeaza o secventa de actiuni (reprezentate in programe prin instructiuni) asupra obiectului caruia ii apartine. Actiunile realizate de executia metodelor au in general efect asupra valorilor campurilor (atributelor) obiectului. Efectele acestor actiuni pot fi combinatii intre:

   - modificarea valorilor campurilor obiectului, ca in cazul metodelor de tip setCamp(),

   - obtinerea valorilor campurilor, ca in cazul metodelor de tip getCamp(),

   - realizarea altor sarcini utilizand aceste valori.

 

 

Parametrii specifica valorile de intrare necesare metodelor pentru a fi executate.

 

Declaratiile metodelor (semnaturile) pot include liste de declaratii de parametri. Acesti parametri sunt variabile care au ca scop intregul corp al metodei si se numesc parametri formali sau simplu PARAMETRI. Parametrii formali sunt declarati ca orice variabila, folosind formatul tipVariabila numeVariabila.

 

Apelurile metodelor pot include liste de valori date parametrilor, valori care trebuie sa corespunda ca tip celor declarate. Valorile pasatele metodelor in momentul apelurilor se numesc parametri actuali sau simplu ARGUMENTE. De exemplu, apelul circle1.changeSize(50) specifica valoarea 50 ca argument, utilizat de metoda changeSize() pentru a da valoarea “50” diametrului cercului.

 

Dupa invocare (apelare) metodele obiectelor efectueaza sarcini (in general utilizand argumentele si valorile campurilor obiectului) care se pot finaliza prin returnarea unei valori.

 

Definitia unei metode contine 2 parti: semnatura (antetul, declaratia) si corpul (blocul, segmentul, secventa de instructiuni a implementarii).

 

Semnatura specifica:

- numele metodei,

- lista de parametri formali (numarul, ordinea, tipul si numele lor),

- tipul valorii returnate,

- specificatori ai unor proprietati explicite (modificatori ai proprietatilor implicite).

 

Daca metoda nu returneaza nici o valoare, tipul valorii returnate este declarat void. Tipul valorii returnate poate fi unul dintre cele 8 tipuri primitive Java (byte, short, int, long, float, double, boolean si char), sau unul dintre cele 3 tipuri referinta (tablourile, clasele si interfetele Java).

 

Corpul metodei contine secventa de instructiuni care specifica pasii necesari indeplinirii sarcinilor (evaluari expresii, atribuiri, decizii, iteratii, apeluri metode). Returnarea valorilor este specificata in codul metodelor prin instructiunea return urmata de o expresie care poate fi evaluata la o valoare de tipul declarat in semnatura.

 

 

Constructorul Java este un tip special de functie, care

- are acelasi nume cu numele clasei in care este declarat,

- este utilizat pentru a initializa orice nou obiect de acel tip (stabilind valorile campurilor/ atributelor obiectului, in momentul crearii lui dinamice),

- nu returnează nici o valoare,

- are aceleasi niveluri de accesibilitate, reguli de implementare a corpului si reguli de supraincarcare a numelui ca si metodele obisnuite.

 

In Java nu este neaparat necesara scrierea unor constructori pentru clase, deoarece un constructor implicit este generat automat de sistemul de executie (DOAR) pentru o clasa care nu declara explicit constructori. Acest constructor nu face nimic (nici o initializare, implementarea lui continand un bloc de cod vid: { }). De aceea, orice initializare dorita explicit impune scrierea unor constructori.

 

 

Java suporta supraincarcarea numelor (name overloading) pentru metode si constructori. Astfel, o clasa poate avea orice numar de metode cu acelasi nume cu conditia ca listele lor de parametri sa fie diferite.

 

In mod similar, o clasa poate avea orice numar de constructori (acestia avand toti acelasi nume - identic cu numele clasei) cu conditia ca listele lor de parametri sa fie diferite. De exemplu, codul clasei anterioare poate fi completat cu constructorul:

 

 

Legătura este o cale între obiectele care se cunosc (văd) unul pe altul (îşi pot transmite mesaje – apelurile de metode), pentru aceasta avand referinte unul către celălalt.

 

Un obiect sau o clasa “vede” un alt obiect daca are o referinta catre el, si astfel ii poate apela metodele. Se spune ca exista o legatura intre obiectul care are referinta catre obiectul referit.

 

Fiecărei familii de legături între obiecte ale aceleiasi clase ii corespunde o relaţie între clasele acelor obiecte.

 

Asocierea este o relatie care exprimă un cuplaj (o dependenta) redus între clase (clasele asociate rămânând relativ independente).

 

Asocierile unidirectionale pot fi considerate relatii de utilizare.

 

1.2.2. Tipuri de date

 

Descrierea problemelor reale sub forma de modele reprezentate ca programe de calcul necesita definirea datelor problemei.

 

TIPUL DE DATE este o descriere abstracta a unui grup de entitati asemanatoare.

 

 

Tipul de date defineste structura variabilelor si domeniul de definitie al valorilor.

 

 

Mai exact, tipul de date specifica:

   - spatiul de memorie alocat pentru stocarea valorii campului/parametrului/variabilei (de ex., 4B = 32b pentru tipul int, 1b pentru tipul boolean, etc.);

   - gama/multimea valorilor posibile (-231…231-1 pentru int, valorile true si false pentru boolean);

   - formatul valorilor literale/de tip imediat (de ex., 100000 sau -2000 pentru tipul int, true sau false pentru tipul boolean, etc.) ;

   - regulile privind conversiile catre alte tipuri (de ex., tipul int se poate converti direct, implicit, la tipurile long, float si double, si poate fi convertit explicit, prin cast – conversie prin trunchiere, la tipurile byte si short, pe cand tipul boolean nu poate fi convertit la nici un alt tip, etc.),

   - valorile implicite (doar in cazul campurilor!, 0 pentru tipul int, false pentru tipul boolean, etc.) ;

   - operatorii asociati (permisi) – care tin de partea de prelucrare asupra datelor.

 

 

Tipurile de date primitive Java:

 

Categorie

Tip

Valoare implicita

Spatiu memorie

Gama valori

Conversii explicite

(cast, trunchiere)

Conversii implicite

(extindere)

Valori intregi

cu

semn

byte

0

8 biti (1B)

-128 … 127

La char

La short, int, long, float, double

short

0

16 biti (2B)

-32768 … 32767

La byte, char

La int, long, float, double

int

0

32 biti (4B)

-2147483648 … 2147483647

La byte, short, char

La long, float, double

long

0l

64 biti (8B)

-9223372036854775808 …9223372036854775807

La byte, short, int, char

La float, double

Valori

in

virgula mobile

cu

semn

float

0.0f

32 biti (4B)

+/-1.4E-45 … +/-3.4028235E+38,
+/-infinity, +/-0, NAN

La byte, short, int, long, char

La double

double

0.0

64 biti (8B)

+/-4.9E-324 …

+/-1.8+308,
+/-infinity, +/-0, NaN

La byte, short, int, long, float, char

Nu exista

(nu sunt necesare)

Caractere codificate UNICODE

char

\u0000

(null)

16 biti (2B)

\u0000 … \uFFFF

La byte, short

La int, long, float, double

Valori logice

boolean

false

1 bit folosit din 32 biti

true, false

Nu exista

(nu sunt posibile)

Nu exista

(nu sunt posibile)

 

 

In Java, pe langa tipurile de date primitive, exista si tipuri de date complexe numite tipuri referinta, tablourile si clasele.


 

 

1.3. Studiu de caz

1.3.1. Constructia structurii statice a clasei (doar campurile/atributele)

Sa presupunem ca dorim sa scriem codul unei clase Java numita Student care sa abstractizeze un student real (incapsuland informatii despre el) in cadrul unui program care gestioneaza informatii intr-o universitate, facultate, etc.

 

Pentru inceput ne vom concentra pe proprietatile (atributele, campurile Java) care constituie structura statica (datele, informatiile reprezentate sub forma de variabile) a clasei.

 

Pentru a selecta cateva informatii esentiale pentru modelul software al unui student putem mai intai sa ne imaginam care vor fi cazurile de utilizare (termen utilizat in limbajul UML pentru modelarea sistemelor software OO) ale clasei. Acestea ar putea fi: Inmatriculare, Repartizare in serie/grupa,  Parcurgere semestru, Promovare semestru, Proiect de diploma, Cazare, Absolvire.

 

Putem considera ca esentiale acele informatii care apar in mai multe astfel de cazuri de utilizare, cum ar fi numele studentului (informatie ce tine de persoana sa), cursurile / disciplinele pe care le are de parcurs (care tin de programa de studiu si de alegerile facute de el) si rezultatele / notele obtinute la aceste cursuri.

 

Reprezentand aceste informatii in forma cea mai simpla in limbajul Java rezulta codul:

 

1

2

3

4

5

6

7

8

9

10

  /**
   * Incapsuleaza informatiile despre un Student.
   * @version 1.0
   */
  public class Student {
    // Campuri (atribute) private (inaccesibile codurilor exterioare)
    private String nume;      // nume + prenume intr-un singur sir de caractere
    private String[] cursuri; // numele cursurilor intr-un tablou de siruri
    private int[] rezultate;  // notele asociate cursurilor intr-un tablou de int
  }

 

 

1.3.2. Adaugarea elementelor de comportament ale clasei (metodele/operatiile)

 

Pentru inceput ne vom concentra pe adaugarea metodelor necesare pentru accesul la proprietatile (atributele/campurile) care constituie structura clasei.

Pentru fiecare camp Java vom adauga o metoda de modificare a valorii lui, denumita setCamp(), si o metoda de obtinere a valorii lui, getCamp().

 

 

 

 

1.3.3. Adaugarea claselor DatePersonale si SituatieCurs si reconstructia clasei Student

 

 

Sa presupunem ca dorim sa modificam codul clasei Student care abstractiza un student real, introducand detalii suplimentare referitoare la Student ca persoana, pe langa campul nume.

 

De exemplu, putem inlocui campul nume de tip String cu un camp date de un tip nou, DatePersonale, care va fi o noua clasa ce va contine pe langa un camp nume de tip String si campurile initiale si prenume de tip String si anNastere de tip int.

 

Codul noii clasei va fi:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

package model;

 

public class DatePersonale {

   // Campuri ascunse

   private String nume;

   private String initiale;

   private String prenume;

   private int anNastere;

 

   // Constructori

   public DatePersonale(String n, String i, String p, int an) {

      nume = new String(n);      // copiere „hard” a obiectelor primite ca parametri,

      initiale = new String(i);  // adica se copiaza obiectul camp cu camp,

      prenume = new String(p);   // nu doar referintele ca pana acum

      anNastere = an;

   }

   // Interfata publica si implementarea ascunsa

   public String getNume() {      return (nume);   }

   public String getPrenume() {   return (prenume);   }

   public int getAnNastere() {    return (anNastere);   }

   public String toString() {    // forma „String” a campurilor obiectului

      return (nume + " " + initiale + " " + prenume + " (" + anNastere + ")");

   }

}

 

 

 

De asemenea, presupunem ca dorim sa modificam codul clasei Student regrupand elementele pereche ale campurilor cursuri si rezultate (care sunt tablouri) in obiecte ale unei clase noi, SituatieCurs. Vom inlocui in clasa Student tablourile cursuri cu elemente de tip String si rezultate cu elemente de tip int, cu un singur tablou, cursuri, cu elemente de tip SituatieCurs.

 

 

 

 

Codul Java al noii clasei va fi:                

 

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

package model;

 

public class SituatieCurs {

   // Campuri ascunse

   private int nota = 0;                            // initializare implicita

   private String denumire;

 

   // Constructor

   public SituatieCurs(String d) { denumire = new String(d); }     // copiere „hard”

                                                   // se initializeaza doar denumire

   // Interfata publica si implementarea ascunsa

   public void notare(int n) {     nota = n; }     // se adauga nota

   public int nota() {             return(nota); } // se returneaza nota

   public String toString() {                      // forma „String” a campurilor

      if (nota==0) return ("Disciplina " + denumire + " nu a fost notata");

      else return("Rezultat la disciplina " + denumire + ": " + nota);

   }

}

 

 

 

 

In cele doua clase, se observa ca se foloseste copierea “hard” a obiectelor primite ca parametri, adica crearea unor copii ale obiectelor argument, camp cu camp, nu doar copierea referintelor.

 

In clasa SituatieCurs nu am utilizat metode de tip getCamp() si setCamp(). Metoda nota()ar fi putut fi denumita getNota() iar metoda notare() ar fi putut fi denumita setNota().

 

Printre metodele declarate regasim si toString(), cu scopul de a returna sub forma de String informatiile pe care le incapsuleaza obiectul caruia i se aplica. Nota initiala 0 inseamna notei (notarea poate incepe doar cu 1). De aceea toString() returneaza diferit pentru valori nule/nenule.

 

Vom rescrie acum codul Java al clasei Student pentru a incorpora schimbarile anuntate.

 

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

/** Incapsuleaza informatiile despre un Student. Permite testarea locala.
   * @version 1.3    */

  package model;


  public class Student {

   // Campuri ascunse

   private DatePersonale date;

   private SituatieCurs[] cursuri;

   private int numarCursuri = 0;             // initializare implicita

  

   // Constructori

   public Student(String nume, String initiale, String prenume, int anNastere) {

      date = new DatePersonale(nume, initiale, prenume, anNastere); // copiere „hard”

      cursuri = new SituatieCurs[10];        // se initializeaza doar date si cursuri

   }

   // Interfata publica si implementarea ascunsa (include punct intrare program)

   public void addCurs(String nume) {        // se adauga un nou curs

      cursuri[numarCursuri++] = new SituatieCurs(nume);

   }

   public void notare(int numarCurs, int nota) {

      cursuri[numarCurs].notare(nota);       // se adauga nota cursului specificat

   }

   public String toString() {                // forma „String” a campurilor

      String s = "Studentul " + date + " are urmatoarele rezultate:\n";

      for (int i=0; i<numarCursuri; i++)   s = s + cursuri[i].toString() + "\n";

      return (s);

   }

   public static void main(String[] args) {

      // Crearea unui nou Student, initializarea campurilor noului obiect

      Student st1 = new Student("Xulescu", "Ygrec", "Z.", 1987);

      st1.addCurs("CID");

      st1.addCurs("MN");

      st1.notare(0, 8);

      // Utilizarea informatiilor privind Studentul

      System.out.println(st1.toString());    // afisarea formei „String” a campurilor

   }

}

 

 

Clasa are o metoda main() cu rolul de a testa lucrul cu obiectele Student. Executia ei conduce la:

     Studentul Xulescu A. Ygrec (1987) are urmatoarele rezultate:

     Rezultat la disciplina CID: 8

     Disciplina MN nu a fost notata

 

 

In laborator:

1. Se deschide NetBeans IDE.

2. Se sterg toate proiectele anterior deschise, cu click dreapta in fereastra Projects pe nodul fiecarui proiectul, selectand apoi Delete, si confirmand ca doriti sa fie sterse sursele (in cazul proiectelor Java).

 

 

In laborator:

3. Se creaza un nou proiect cu File > New Project... (sau Ctrl-Shift-N).

4. In zona Categories se selecteaza Java, in zona Projects se selecteaza Java Class Library, se apasa Next.

5. La Project Name se scrie numele ales pentru noul proiect, cum ar fi ModelareStudent, la Project Location se selecteaza/creeaza subdirectorul corespunzator serie, grupei si subgrupei proprii (calea va fi de genul: C:\TPI\433D\pare).

 

·       Alegerea tipului de proiect: Java Class Library

 

·       Definirea detaliilor de proiect (nume proiect, locatie fizica, clasa principala (main class)). In final se apasa butonul Finish

 

·       Evidentierea detaliilor proiectului:

 

 

In laborator:

6. Se adauga un nou fisier sursa cu File > New File... (sau Ctrl- N).

7. In zona Categories se selecteaza Java si in zona FileTypes se selecteaza Java Class, se apasa Next.

8. In zona.in zona Class Name se scrie numele Student,  in zona Package se scrie numele model

(nu Model sau alta varianta!!!)

9. Se inlocuieste codul generat automat cu codul de mai sus.

 

·       Click dreapta pe pachetul in care doriti plasarea noii clase, apoi selectarea New/Java Class

 

 

 

·       Atribuirea numelui noii clase (in cazul nostru Student), restul detaliilor fiind precompletate de catre NetBeans

 

 

·       Evidentierea noii clase si completarea clasei cu codul Java dorit

 

 

 

In laborator:

10. In proiectul ModelareStudent se adauga un noi fisiere sursa cu File > New File... (Ctrl- N), cu numele DatePersonale si SituatieCurs, in pachetul model.

11. Se inlocuieste codul generat automat cu codul de mai sus.

12. Se selecteaza Build pe nodul de proiect al proiectului (ModelareStudent sau numele ales)

13. Se selecteaza Run File pe nodul clasei cu numele Student.

 

1.3.4. Exercitii in laborator

 

- modificare metoda notare() (in clasa SituatieCurs)

     pentru a nu permite notarea in afara gamei 1-10

     avertizand utilizatorul in cazul unei note in afara gamei

 

- adaugare in clasa Student a unei metode nota()

     care returneaza nota pentru indexul primit cursului ca parametru

 

- adaugare in clasa Student a unei metode medieCurenta()

     care returneaza media notelor curente

 

- ...

 

- bonusuri pentru propuneri interesante de exercitii in laborator!


 

 

 

1.4. Extinderea prin mostenire

1.4.1. Generalizarea si specializarea claselor

 

Generalizarea reprezinta extragerea elementelor comune (atribute, operaţii şi constrângeri) ale unui ansamblu de clase într-o nouă clasă mai generală numită superclasă (care reprezinta o abstracţie a subclaselor ei).

 

Rezulta o ierarhie in care arborii de clase sunt construiţi pornind de la frunze, atunci cand elementele modelului au fost identificate, obţinandu-se o descriere generica si flexibila a soluţiilor.

 

Generalizarea semnifică relatia de tip "este un" atunci cand un obiect dintr-o clasa din ansamblul generalizat este in acelasi timp si obiect al superclasei, si de tip "este un fel de" atunci cand un obiect dintr-o clasa din ansamblul generalizat este doar aproximativ si obiect al superclasei (aproximatia venind din rescrierile codurilor operate in clasa generalizata).

 

Generalizarea actioneaza in orientarea spre obiecte la doua niveluri:

- clasele sunt generalizari ale ansamblurilor de obiecte (un obiect este de felul definit de o clasa),

- superclasele sunt generalizari ale unor clase (obiectele de felul specificat intr-o clasa sunt in acelasi timp si de felul specificat in superclasa).

Orientarea spre obiecte (OO) presupune ambele tipuri de generalizare, iar limbajele orientate spre obiecte sunt acelea care ofera ambele mecanisme de generalizare. Limbajele care ofera doar constructii numite obiecte (si eventual clase) se pot numi limbaje care lucreaza cu obiecte (si eventual clase).

 

Specializarea claselor reprezinta capturarea particularităţilor unui ansamblu de obiecte nediscriminate ale unei clase existente, noile caracteristici fiind reprezentate într-o nouă clasă mai specializată, denumită subclasă.

 

Specializarea usureaza extinderea coerentă a unui ansamblu de clase, noile cerinţe fiind încapsulate în subclase care extind funcţiile existente.

 

 

1.4.2. Mostenirea. Rescrierea codului metodelor (overriding)

 

Moştenirea este o tehnică de generalizare oferită de limbajele de programare orientate spre obiecte pentru a construi o clasă pornind de la una sau mai multe alte clase, partajând atributele si operaţiile (campurile si metodele, in Java) într-o ierarhie de clase.

In limbajul Java, orice clasa care nu extinde in mod explicit (prin mostenire) o alta clasa Java, extinde (prin mostenire) in mod implicit clasa Object (radacina ierarhiei de clase Java), clasa care contine metodele necesare tuturor obiectelor create din ierarhia de clase Java. Urmatoarele doua declaratii de clasa sunt echivalente:

 

 

    class NumeClasa {                // urmeaza corpul clasei ...

 

 

    class NumeClasa extends Object { // urmeaza corpul clasei ...

 

1.5. Studiu de caz: clasele Persoana, Student, Profesor si StudentMaster

1.5.1. Clasele Persoana si Profesor si actualizarea clasei Student

 

 

 

Sa presupunem ca dorim sa adaugam o clasa Profesor care abstractizeaza un profesor real, prin intermediul unui camp date de tip DatePersonale, si a unui camp titlu de tip String.

 

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

 /** Incapsuleaza informatiile despre un Profesor. Permite testarea locala.
   * @version 1.3
   */
  public class Profesor {

   // Campuri ascunse

   private DatePersonale date;

   private String titlu;

  

   // Constructori

   public Profesor(String nume, String initiale, String prenume, int anNastere) {

      date = new DatePersonale(nume, initiale, prenume, anNastere); // copiere „hard”

   }

 

   // Interfata publica si implementarea ascunsa (include punct intrare program)

   public void setTitlu(String t) { 

      titlu = new String(t);      // copiere „hard” a obiectului primit ca parametru

   }

   public String toString() {                // forma „String” a campurilor

      return ("Profesorul " + date + " are titlul " + titlu);

   }

   public static void main(String[] args) {

      // Crearea unui nou Profesor, initializarea campurilor noului obiect

      Profesor pr = new Profesor("Nulescu", "Ion", "A.", 1960);

      pr.setTitlu("Lector Dr.");

      // Utilizarea informatiilor privind Profesorul

      System.out.println(pr.toString());    // afisarea formei „String” a campurilor

   }

  }

 

Se observa ca avem un camp (date) comun cu clasa Student.

 

Putem crea o clasa Persoana care sa contina acest element comun, rescriind apoi codurile claselor Profesor si Student pentru a extinde clasa Persoana (si a-i refolosi campul date).

Codul noii clase Persoana va fi:

 

 

 

 

 

 

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

 /**  Incapsuleaza informatiile despre o Persoana. Permite testarea locala.
   * @version 1.4
   */
 public class Persoana {

   // Campuri ascunse

   protected DatePersonale date;

  

   // Constructori

   public Persoana(String nume, String initiale, String prenume, int anNastere) {

      date = new DatePersonale(nume, initiale, prenume, anNastere); // copiere „hard”

   }

   // Interfata publica si implementarea ascunsa (include punct intrare program)

   public String toString() {                  // forma „String” a campurilor

      return (super.toString());

   }

   public static void main(String[] args) {

      // Crearea enei noi Persoane, initializarea campurilor noului obiect

      Persoana p = new Persoana("Julescu", "Ion", "C.", 1965);

      // Utilizarea informatiilor privind Persoana

      System.out.println(p.toString());    // afisarea formei „String” a campurilor

   }

 }

 

 

Vom rescrie acum codul clasei Profesor pentru a incorpora schimbarile anuntate.

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

 /** Incapsuleaza informatiile despre un Profesor. Permite testarea locala.
   * @version 1.4
   */
  public class Profesor extends Persoana {

   // Campuri ascunse

   protected String titlu;

  

   // Constructori

   public Profesor(String nume, String initiale, String prenume, int anNastere) {

      super(nume, initiale, prenume, anNastere); // apel constructor supraclasa

   }                                             // (reutilizare cod)

 

   // Interfata publica si implementarea ascunsa

   public void setTitlu(String t) { 

      titlu = new String(t);       // copiere „hard” a obiectului primit ca parametru

   }

 

   public String toString() {                // forma „String” a campurilor

      return ("Profesorul " + date + " are titlul " + titlu);

   }

   public static void main(String[] args) {

      // Crearea unui nou Profesor, initializarea campurilor noului obiect

      Profesor pr = new Profesor("Nulescu", "Ion", "A.", 1960);

      pr.setTitlu("Lector Dr.");

      // Utilizarea informatiilor privind Profesorul

      System.out.println(pr.toString());    // afisarea formei „String” a campurilor

   }

  }

 

 

 

Vom rescrie acum codul clasei Student pentru a incorpora schimbarile anuntate.

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

/**  Incapsuleaza informatiile despre un Student. Permite testarea locala.
   * @version 1.4
   */
  public class Student extends Persoana {

   // Campuri ascunse

   protected SituatieCurs[] cursuri;

   protected int numarCursuri = 0;             // initializare implicita

  

   // Constructori

   public Student(String nume, String initiale, String prenume, int anNastere) {

      super(nume, initiale, prenume, anNastere); // apel constructor supraclasa

      cursuri = new SituatieCurs[10];        // se initializeaza doar date si cursuri

   }

 

   // Interfata publica si implementarea ascunsa (include punct intrare program)

   public void addCurs(String nume) {        // se adauga un nou curs

      cursuri[numarCursuri++] = new SituatieCurs(nume);

   }

 

   public void notare(int numarCurs, int nota) {

      cursuri[numarCurs].notare(nota);       // se adauga nota cursului specificat

   }

 

   public String toString() {                // forma „String” a campurilor

      String s = "Studentul " + date + " are urmatoarele rezultate:\n";

      for (int i=0; i<numarCursuri; i++)   s = s + cursuri[i].toString() + "\n";

      return (s);

   }

 

   public static void main(String[] args) {

      // Crearea unui nou Student, initializarea campurilor noului obiect

      Student st1 = new Student("Xulescu", "Ygrec", "Z.", 1987);

      st1.addCurs("CID");

      st1.addCurs("MN");

      st1.notare(0, 8);

      // Utilizarea informatiilor privind Studentul

      System.out.println(st1.toString());    // afisarea formei „String” a campurilor

   }

  }

 

 

 

 

Codul clasei DatePersonale ramane nemodificat:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

public class DatePersonale {

   // Campuri ascunse

   private String nume;

   private String initiale;

   private String prenume;

   private int anNastere;

 

   // Constructori

   public DatePersonale(String n, String i, String p, int an) {

      nume = new String(n);      // copiere „hard” a obiectelor primite ca parametri,

      initiale = new String(i);  // adica se copiaza obiectul camp cu camp,

      prenume = new String(p);   // nu doar referintele ca pana acum

      anNastere = an;

   }

   // Interfata publica si implementarea ascunsa

   public String getNume() {      return (nume);   }

   public String getPrenume() {   return (prenume);   }

   public int getAnNastere() {    return (anNastere);   }

   public String toString() {    // forma „String” a campurilor obiectului

      return (nume + " " + initiale + " " + prenume + " (" + anNastere + ")");

   }

}

 

 

Codul clasei SituatieCurs ramane nemodificat:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

public class SituatieCurs {

   // Campuri ascunse

   private int nota = 0;                            // initializare implicita

   private String denumire;

 

   // Constructor

   public SituatieCurs(String d) { denumire = new String(d); }     // copiere „hard”

                                                   // se initializeaza doar denumire

   // Interfata publica si implementarea ascunsa

   public void notare(int n) {     nota = n; }     // se adauga nota

   public int nota() {             return(nota); } // se returneaza nota

   public String toString() {                      // forma „String” a campurilor

      if (nota==0) return ("Disciplina " + denumire + " nu a fost notata");

      else return("Rezultat la disciplina " + denumire + ": " + nota);

   }

}

 

1.5.2. Clasa StudentMaster

 

Sa presupunem ca dorim sa scriem codul unei clase noi numita StudentMaster care sa abstractizeze un anumit subtip al tipului Student, prin adaugarea la codul clasei Student a unui camp numit specializare de tip String. Relatiile de utilizare (linie punctata) si mostenire (sageti cu triunghi in capat) in UML:

 

 

Putem scrie codul acestei clase care extinde clasa Student astfel:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

/**  Incapsuleaza informatiile despre un Student. Permite testarea locala.
   * @version 1.4
   */
  public class StudentMaster extends Student {

   // Campuri ascunse

   private String specializare;

  

   // Constructori

   public StudentMaster(String nume, String initiale, String prenume, int anNastere) {

      super(nume, initiale, prenume, anNastere); // apel constructor supraclasa

   }

 

   // Interfata publica si implementarea ascunsa (include punct intrare program)

   public void setSpecializare(String spec) {        // se stabileste specializarea

      specializare = new String(spec);   // copiere „hard” a obiectului primit

   }

   public String toString() {                // forma „String” a campurilor

      String s = "Studentul " + date + " cu specializarea " + specializare +

                                                " are urmatoarele rezultate:\n";

      for (int i=0; i<numarCursuri; i++)   s = s + cursuri[i].toString() + "\n";

      return (s);

   }

   public static void main(String[] args) {

      // Crearea unui nou Student, initializarea campurilor noului obiect

      StudentMaster sm = new StudentMaster("Rulescu", "Ygrec", "T.", 1983);

      sm.addCurs("Securitate Retele");

      sm.addCurs("Servicii Web");

      sm.setSpecializare("Retele si Software de Telecomunicatii");

      sm.notare(0, 9);

      // Utilizarea informatiilor privind Studentul

      System.out.println(sm.toString());    // afisarea formei „String” a campurilor

   }

  }

 

 

 

In laborator:

1. In proiectul ModelareStudent se adauga un noi fisiere sursa cu File > New File... (Ctrl- N), cu numele Persoana, Profesor si StudentMaster, in pachetul model.

2. Se inlocuieste codul generat automat cu codul de mai sus.

3. Se inlocuieste codul anterior al clasei Student cu codul de mai sus.

4. Se selecteaza Build pe nodul de proiect al proiectului ModelareStudent.

5. Se selecteaza Run File pe nodul clasei cu numele Student.

6. Se selecteaza Run File pe nodul clasei cu numele Profesor.

7. Se selecteaza Run File pe nodul clasei cu numele StudentMaster.

8. Se selecteaza Run File pe nodul clasei cu numele Grupa.

 

Atentie: La inceputul laboratoarelor stergeti mai intai toate proiectele existente (click dreapta pe

 nodul proiectului in fereastra Projects si selectati Delete, si confirmati ca doriti sa fie sterse

 surselein cazul proiectelor Java). La finalul laboratoarelor stergeti proiectele create.

 

Kituri si documentatie: netbeans-6.1-windows.exe, jdk-6u5-windows-i586-p.exe, Javadoc.zip,

jdk-6u5-windows-amd64.exe, jdk-6u5-windows-x64.exe

 

Anexa        

1. Instalarea kitului Java (pe sistemul de operare Windows XP)

 

 

1.1. Se lanseaza kitul Java (exemplul este scris pentru versiunea jdk-6u5-windows-i586-p.exe)

> jdk-6u5-windows-i586-p.exe

 

 

1.2. Se confirma TOATE optiunile implicite!!

 

 

1.3. Start -> Control Panel ( -> Switch to Classic View ) -> System -> Advanced -> Environment Variables

 

 

1.4. La System Variables (NU la User!!) se apasa New

 

 

1.5. La Variable name se adauga variabila de mediu CLASSPATH

 

 

1.6. La Variable value se scrie:

C:\Program Files\Java\jdk1.6.0_05\lib;.;

 

(daca harddisk-ul pe care s-a facut instalarea este C:, altfel se inlocuieste C: corespunzator)

Atentie: acel punct aflat intre cele doua semne ; este foarte important, el permite executia

programelor din directorul current din linie de comanda

 

1.7. Se cauta variabila de mediu Path se selecteaza si se apasa Edit

 

 

1.8. La Variable value se adauga LA FINAL (dupa ultimul caracter):

;C:\Program Files\Java\jdk1.6.0_05\bin;

 

(daca harddisk-ul pe care s-a facut instalarea este C:, altfel se inlocuieste C: corespunzator)

 

 

1.9. Se lanseaza consola cu Start -> Run se scrie

cmd  <Enter>

 

(adica se apasa <Enter>)

 

 

1.10. In consola se alege un director dorit pentru testarea instalarii kitului

(cu       > cd \ <Enter>             se ajunge in radacina C:\> ,

cu        > cd.. <Enter>             se ajunge in directorul al carui subdirector este directorul curent,

cu        > cd <subdirector> <Enter> se ajunge intr-un subdirector,

cu        > D: <Enter>                          se schimba harddiskul in D:)

 

 

1.11. In directorul ales se creaza cu un editor un fisier numit Test.java, cu urmatorul continut:

 

public class Test {

public static void main(String[] args) {

System.out.println("Kitul Java a fost instalat cu succes!");

}

}

 

1.12. In consola se scrie (pentru compilare) :

> javac Test.java  <Enter>

(daca nu sunt probleme, apare un nou prompt fara vreun mesaj)

 

1.13. In consola se scrie (pentru executie in masina virtuala Java – JVM):

> java Test <Enter>

 

1.14. Astfel in consola va aparea mesajul:

Kitul Java a fost instalat cu succes!

 

2. Instalarea kitului NetBeans (DUPA instalarea kitului Java)

 

2.1. Se lanseaza (exemplul este scris pentru versiunea 6.1)

> netbeans-6.1-windows.exe

 

2.2. Se confirma TOATE optiunile implicite!!

 

2.3. Cand se cere specificarea kitului Java se selecteaza:

C:\Program Files\Java\jdk1.6.0_05