Laborator 7.
1.
Polimorfism
Polimorfismul permite
folosirea unui obiect in locul altui obiect (o unei subclase in locul
unei superclase). Prin aceasta sprijina scrierea de cod eficient cu costuri
de dezvoltare si intretinere reduse.
Este
sustinut doar de limbajele care permit legarea intarziata
la apelul metodelor. Acest lucru se refera la modalitatea in care sunt
generate in programul executabil apelul rutinelor din program.
La limbajele cu "legare
timpurie" adresa la care se face un apel spre o rutina se stabileste
la compilare si este scrisa in mod univoc in codul obiect rezultat.
La limbajele cu legare
intarziata, adresa de apel a unei rutine (metode in cazul Java) se stabileste
doar in momentul rularii, functie de contextul in care apare apelul. In
acest fel, spre exemplu, daca se declara o referinta spre o clasa Persoana
care indica spre un obiect de tip Student, un apel al metodei afiseaza_date()
va apela corect metoda cu acest nume din clasa Student si pe cea din Persoana.
Pentru exemplificare
se considera exemplul din figura urmatoare:

Clasa Bird este o clasa abstracta care modeleaza conceptul de pasare.
Din ea sunt derivate doua clase concrete si anume Goose (gasca) si Penguin
(pinguin).
Pentru gestionarea migratiei pasarilor se foloseste o clasa separata
numita BirdControler. Aceasta clasa pune la dispozitie o metoda pentru
realizarea migrarii denumita reLocate(). Problema rezida in a realiza
corect deplasarea. In acest sens Gasca
poate implementa move() prin apelulul metodei proprii zboara(). Analog,
Pinguinul poate implementa move() prin apelulul metodei proprii inoata().
In momentul cand este apelata metoda reLocate() din BirdControler, aceasta
va invoca corect metodele move() din subclasele clasei Bird. Rezultatul
este ca pinguinul va inota iar gasca va zbura pentru a reliza migrarea,
chiar daca clasa BirdControler pastreaza referinte doar spre clasa Bird.
Din acest exeplu rezulta
de asemenea avantaje la nivelul implementarii si testarii. Informatii
despre o noua pasare pot fi adaugate simplu, fara a modifica clasa BirdControler.
In acest sens este suficient sa se deriveze o noua clasa din Bird, iar
aceasta sa implementeze propria metoda move(). Este evident ca adaugarea
acestei clase nu introduce erori in clasele existente deja, ca atare codul
care implementeaza procesul de migratie nu mai trebuie retestat.
Polimorfismul se utilizeaza des pentru a trata unitar colectii de obiecte
diferite. Un exemplu in acest sens este tablou de Aparate din laboratorul
referitor la Interfete Java.

Datorita suportului pentru polimorfism, urmatoarea secventa de cod apeleaza
corect metoda proprie de pornire a fiecarui aparat in parte:
Aparat aparate[] = new Aparat[6];
aparate[0] = new Fax(1440, 230);
aparate[1] = new Calculator(1200, 256, 350);
aparate[2] = new Monitor(17, 130);
aparate[3] = new Radio("Panasonic", 80);
aparate[4] = new Bec(200);
aparate[5] = new Radiator(2000);
for (i=0; i<aparate.length; i++)
aparate[i].porneste();
Referinta: Interfete.java.
2.
Colectii de obiecte in Java
Aproape toate programele reale utilizeaza colectii de obiecte. De asemenea,
toate limbajele de programare de nivel inalt implementeaza intr-o forma
sau alta tipul array (tablou de elemente).
In Java, variabilele de tip array sunt considerate obiecte, avand
asociate, pe langa setul de elemente continute si un atribut length
care da informatii despre numarul de elemente si o metoda clone()
care ofera posibilitatea crearii unei copy a tabloului original.
Pe langa tipul array, pentru gestionarea acestor colectii de obiecte
limbajul Java pune la dispozitie clase specializate, reunite in pachetul
java.util. Acest pachet contine doua ierarhii principial diferite:
Collection (multimi de obiecte) si Map (seturi tip cheie->valoare).
3.
Ierahia Collection
Ierarhia derivata din Collection cuprinde doua tipuri de clase:
- List (permite duplicate, defineste o ordonare a elementelor)
- Set (nu permite duplicate)
Din ierarhia List fac parte: ArrayList si LinkedList.
Ierarhia Set cuprinde: HashSet si TreeSet.
Metode definite de interfata comuna Collection:
- add(), addAll() - adauga la colectie obiectul transmis,
respectiv toate elementele colectiei transmise
- clear() - goleste colectia
- contains(), containsAll() - verifica daca in colectie
se gaseste obiectul transmis, respectiv daca in colectie este inclusa
colectia transmisa
- remove() - elimina obiectul dat ca si parametru
- toArray() creaza un tablou continand elementele colectiei
- size() returneaza numarul de elemente al colectiei
Metode definite de interfata List:
- addFirst() adauga un element la inceputul listei
- addLast() adauga un element la sfarsitul listei
- getFirst() intoarce primul element din lista
- getLast() intoarce ultimul element din lista
- removeFirst() sterge primul element din lista
- removeLast() - sterge ultimul element din lista
Clasele care implementeaza aceasta interfata sunt ArrayList (pentru
situaltiile cand se doreste acces aleator la elemente), LinkedList
(pentru situatiile cand se efectuaeaza acces secvential la elementele
listei). Un caz special Vector, derivata din AbstractList
si care implementeaza un tablou unidimensional dinamic, adaugand la tipul
array o metoda setSize() care redimensioneaza tabloul cand
este necesar.
Exemplu de utilizare liste pentru implementarea unei stive (structura
LIFO - last in, first out):
|
Activitate:
Compilati si
rulati programul urmator (fisierul Stiva.java).
import java.util.*;
/**
* Stiva - clasa pentru exemplificarea implementarii unei stive
* de numere intregi
* LIFO (last in - first out (primul intrat, ultimul extras))
*
* @version 1.0 03 Apr 2003
* @author Dan Pescaru
*/
class Stiva extends LinkedList {
public Stiva() {
super();
}
public void adauga(int nr) {
Integer n = new Integer(nr);
addFirst(n);
}
public void afiseaza() {
System.out.print("Continutul
stivei:");
System.out.println(this);
}
public Integer extrage() {
return (Integer)removeFirst();
}
public static void main(String args[]) {
Stiva stiva = new Stiva(); //
declarare stiva
stiva.adauga(3);
stiva.afiseaza();
stiva.adauga(8);
stiva.afiseaza();
stiva.adauga(5);
stiva.afiseaza();
stiva.adauga(1);
stiva.afiseaza();
Integer i = stiva.extrage();
//se extrage ultimul adaugat
System.out.println("S-a
extras elemtul: "+i);
stiva.afiseaza();
}
}
|
Metode definite de interfata Set:
- add() adauga un element la multime (daca nu exista)
- addAll() adauga o colectie de elemente la multime
- contains() verifica apartenenta unui element la multime
- isEmpty() true daca multimea este vida
- remove () sterge elementul specificat, daca exista
- removeAll() - sterge o colectie de elemente din multime
Clasele care implementeaza aceasta interfata sunt HashSet (implementare
rapida) si TreeSet (pentru acces ordonat la elementele multimii).
Exemplu de utilizare multimi:
|
Activitate:
Compilati si
rulati programul urmator (fisierul MultimeAnimale.java).
import java.util.*;
/**
* MultimeAnimale - clasa pentru exemplificarea implementarii unei
* multimi de animale
*
* @version 1.0 03 Apr 2003
* @author Dan Pescaru
*/
class MultimeAnimale extends HashSet {
public MultimeAnimale() {
super();
}
public void adauga(String animal) {
add(animal);
}
public void afiseaza() {
System.out.print("Animalele
retinute:");
System.out.println(this);
}
public void afiseazaOrdonat() {
System.out.print("Animalele
ordonate alfabetic:");
System.out.println(new TreeSet(this));
}
public static void main(String args[]) {
MultimeAnimale multimeAnimale
= new MultimeAnimale();
multimeAnimale.adauga("Urs");
multimeAnimale.adauga("Rinocer");
multimeAnimale.adauga("Viezure");
multimeAnimale.adauga("Cerb");
multimeAnimale.adauga("Lup");
multimeAnimale.adauga("Bizon");
multimeAnimale.afiseaza();
multimeAnimale.afiseazaOrdonat();
}
}
|
4.
Iteratori
Pentru a aprcurge elementele unei multimi care implementeaza interfata
Collection se pot utiliza structuri de date suplimentare numite
iteratori.
Un iterator este un obiect care poate realiza traversarea in ordine a
colectiei la care este atasat. Ordinea de parcurgere este determinata
de maniera in care sunt retinute elementele in colectie.
Interfata Iterator contine urmatoarele declaratii:
interface Iterator {
boolean hasNext();
Object next();
void remove();
}
Metoda iterator() declarata in interfata Collection creaza
si returneaza referinta la un iterator asociat cu colectia curenta.
Utilizarea unui iterator se realizeaza dupa modelul:
Collection colectie = new ...
Iterator iteratorColectie = colectie.iterator();
...
while( iteratorColectie.hasNext()) {
TipObject element = (TipObiect)iteratorColectie.next();
// prelucrare element curent
// ex. afisare: System.out.println(element);
}
|
Activitate:
Compilati si
rulati programul urmator (fisierul MultimeAnimale1.java).
import java.util.*;
/**
* MultimeAnimale1 - clasa pentru exemplificarea implementarii unei
* multimi de animale parcursa printr-un iterator
*
* @version 1.0 03 Apr 2003
* @author Dan Pescaru
*/
class MultimeAnimale1 extends HashSet {
...
public void afiseaza() {
Iterator iteratorAnimale = this.iterator();
System.out.println("Animalele
retinute: { ");
while( iteratorAnimale.hasNext())
{
String animal
= (String)iteratorAnimale.next();
System.out.println("->
"+animal);
}
System.out.println(" }");
}
...
}
|
5.
Ierahia Map
Ierarhia Map are de asemenea doua tipuri:
- HashMap (cheile nu sunt ordonate, prelucrarea este rapida)
- TreeMap (cheile sunt ordonate in ordine ascendenta rezultand
o viteza mai mica de prelucrare)
Metode definite de interfata Map:
- clear() goleste multimea
- put() adauga un obiect asociat unei chei
- containsKey() verifica existenta unei chei
- containsValue() verifica existenta unui obiect
- get() returneaza obiectul asociat unei chei
- isEmpty() true daca multimea este vida
- remove () sterge cheia specificata
- size() returneaza numarul de elemente
Clasele care implementeaza aceasta interfata sunt HashMap (implementare
rapida, fara ordonare) si TreeMap (cheile ordonate crescator).
|
Activitate:
Compilati si
rulati programul urmator (fisierul Dictionar.java).
import java.util.*;
import java.io.*;
/**
* Dictionar - clasa pentru exemplificarea implementarii unei
* multimi de tip map care asociaza cuvinte de explicatiile lor
*
* @version 1.0 03 Apr 2003
* @author Dan Pescaru
*/
public class Dictionar extends TreeMap{
public Dictionar() {
super();
}
public void adaugaCuvant(String cuvant, String
explicatie) {
Object vechi = put(cuvant, explicatie);
if(vechi != null)
System.out.println("Explicatia
a fost schimbata!");
else
System.out.println("cuvantual
a fost adaugat!");
}
public String cautaCuvant(String cuvant) {
return (String)get(cuvant);
}
public void afisDictionar() {
System.out.println(this);
}
public static void main(String args[]) throws
Exception {
Dictionar dict = new Dictionar();
char raspuns;
String linie, explic;
BufferedReader fluxIn = new
BufferedReader(new InputStreamReader(System.in));
do {
System.out.println("Meniu");
System.out.println("a
- adauga cuvant");
System.out.println("c
- cauta cuvant");
System.out.println("l
- listeaza dictionar");
System.out.println("e
- iesi");
linie = fluxIn.readLine();
raspuns =
linie.charAt(0);
switch(raspuns)
{
case
'a': case 'A':
System.out.println("Citeste
cuvant:");
linie
= fluxIn.readLine();
if(
linie.length()>1) {
System.out.println("Citeste
exmplic:");
explic
= fluxIn.readLine();
dict.adaugaCuvant(linie,
explic);
}
break;
case
'c': case 'C':
System.out.println("Cuvant
cautat:");
linie
= fluxIn.readLine();
if(
linie.length()>1) {
explic
= dict.cautaCuvant(linie);
if
(explic == null)
System.out.println("nu
exista");
else
System.out.println("Explicatie:"+explic);
}
break;
case
'l': case 'L':
System.out.println("Afiseaza:");
dict.afisDictionar();
break;
}
} while(raspuns!='e' &&
raspuns!='E');
}
}
|
6.
Teme
Tema1. Dupa modelul
prezentat in Activitatea in care s-a implementat structura Stiva, creati
o clasa Coada care sa implementeze o structura de coada dupa principiul
FIFO (first in, first out - primul venit, primul extras).
Tema2. Modificati
exemplul "Interfete.java" care cuprinde ierarhia de Aparate
electrice si electronice adaugand o clasa ColectieAparate derivata din
LinkedList care sa permita operatii precum afiseaza colectie, porneste/opreste
toate aparatele, respectiv opresteSeara, pornesteDimieata toate aparatele
care permit asa ceva. La implementarea operatiilor, parcurgerea listei
se va face prin iteratori.
Tema3 (optionala).
Modificati exemplul Dictionar astfel incat sa permita salvarea, respectiv
incarcarea intr-un fisier text al dictionarului prin metode specifice
adaugate clasei.
|