Documente Academic
Documente Profesional
Documente Cultură
O clase conţine atribute şi metode. Metodele se compun dintr-un capul (prototip) şi un corp.
Capul de metodă reprezintă interfaţa unui obiect cu lumea exterioară.
Interfeţele permit, ca şi clasele, definirea unor noi tipuri de date. O interfaţă Java defineşte
un set de metode dar nu specifică nici o implementare pentru ele. O clasă care implementează o
interfaţă trebuie obligatoriu să specifice implementări pentru toate metodele interfeţei,
supunându-se aşadar unui anumit comportament.
Pentru că este posibil ca o clasă să implementeze mai mult de o interfaţă, interfeţele
reprezintă o alternativă pentru moştenirea multiplă, care nu este permisă în Java.
O interfaţă poate avea un singur modificator şi anume public. O interfaţă publică este
accesibilă tuturor claselor, indiferent de pachetul din care fac parte, implicit nivelul de acces fiind
doar la nivelul pachetului din care face parte interfaţa.
Spre deosebire de moştenirea claselor, cuvântul cheie extends permite specificarea a mai
multor interfeţe, separate prin virgulă, care pot fi combinate într-o unitate logică mai mare.
interface Test{
int PI = 3.14;
// Echivalent cu:
public static final int PI = 3.14;
1
Metode membre – fără implementare
Modificatorii pentru metode se limitează la: public. Acesta este implicit, prezenţa lui nefiind
necesară, dar uşurează înţelegerea codului.
interface Test{
void functie();
// Echivalent cu:
public void functie();
}
O clasă poate implementa oricâte interfeţe sau nici una. In cazul în care implementează o
anumită interfaţă, atunci trebuie obligatoriu să specifice cod pentru toate metodele interfeţei
respective.
Interfeţele şi superclasele nu se exclud reciproc. O clasă nouă poate fi derivată dintr-o
superclasă şi poate implementa una sau mai multe interfeţe.
Modificarea unei interfeţe (adăugarea unor metode noi sau schimbarea signaturii metodelor
existente) implică modificarea tuturor claselor care implementează acea interfaţă.
O clasă poate avea şi alte metode şi variabile membre în afară de cele definite în interfaţă.
Implementarea unei interfeţe poate să fie şi o clasă abstractă.
interface Ceas {
public String citesteTimpul();
}
2
Output-ul va fi:
CeasCuLimbi 1 2 3 4 5 6 7 8
CeasElectronic 8:28:11
Ceas c;
c = new Ceas(); //Eroare, nu se pot instanta obiecte de tip Ceas
c=new CeasCuLimbi(); //Corect, pt. ca CeasCuLimbi implementeaza Ceas
import java.util.*;
Întrucât câmpurile sunt statice ele vor fi iniţializate la prima încărcare a clasei, ceea ce are
loc la primul acces a unuia dintre câmpuri.
Gruparea de constate
Interfeţele sunt instrumente utile pentru a realiza o grupare de constante, dată fiind natura
statică şi finală a câmpurilor acestora.
Valorile acestor constant pot fi accesate din exterior prin expresii de forma
Lunile.NOIEMBRIE, evident că rezultatul va fi un int. Pentru obţinerea unei siguranţe de tip
(type safety) mai ridicate se poate scrie o clasă de forma:
3
public final class Luni {
private String nume;
private Luni(String nl) { nume = nl; }
public String toString() { return nume; }
public static final Luni IAN = new Luni("Ianuarie"),
FEB = new Luni("Februarie"),
MAR = new Luni("Martie"),
APR = new Luni("Aprilie"),
MAI = new Luni("Mai"),
IUN = new Luni("Iunie"),
IUL = new Luni("Iulie"),
AUG = new Luni("August"),
SEP = new Luni("Septembrie"),
OCT = new Luni("Octombrie"),
NOI = new Luni("Noiembrie"),
DEC = new Luni("Decembrie");
public static final Luni[] lunile = {
IAN, FEB, MAR, APR, MAI, IUN,
IUL, AUG, SEP, OCT, NOI, DEC
};
public static final Luni numar(int ord) {
return lunile[ord - 1];
}
public static void main(String[] args) {
Luni m = Luni.IAN;
System.out.println(m);
m = Luni.numar(12);
System.out.println(m);
System.out.println(m == Luni.DEC);
System.out.println(m.equals(Luni.DEC));
System.out.println(Luni.lunile[3]);
}
}
Output-ul este
Ianuarie
Decembrie
true
true
Aprilie
Luni este o clasă finală cu constructor privat, aşa că nu pot exista derivări sau instanţe ale
acestei clase. Singurele instanţe, sunt cele finale şi statice create în interiorul clasei: IAN, FEB, etc.
Ele sunt folosite şi în vectorul lunile ceea ce permite o iteraţie pe un vectori de obiecte de tip
Luni. Metoda numar() permite selectarea unei luni pe baza unui număr dat.
În funcţia principală variabila m este un obiect de tip Luni, spre deosebire de exemplul de
mai sus, unde era de tip int, permiţând astfel o asociere cu orice valoare întreagă.
4
Interfeţe pentru compararea obiectelor
O soluţie simplă de sortare a unui vector este folosirea metodei sort din clasa
java.util.Arrays.
În cazul în care elementele din vector sunt de tip primitiv nu există nici o problemă în a
determina ordinea firească a elementelor.
Pentru a vedea ce se întâmplă atunci când vectorul conţine referinţe la obiecte să
considerăm următorul exemplu, în care urmărim să sortăm un vector format din instanţe ale
clasei Persoana.
class Persoana {
int cod ;
String nume ;
public Persoana ( int cod , String nume ) {
this.cod = cod;
this.nume = nume ;
}
public String toString () {
return cod + " \t " + nume ;
}
Interfaţa Comparable
Interfaţa Comparable impune o ordine totală asupra obiectelor unei clase ce o
implementează. Această ordine este specificată prin intermediul metodei compareTo. Definiţia
interfeţei este:
Aşadar, o clasă ale cărei instanţe trebuie să fie comparabil între ele va implementa metoda
compareTo care poate returna:
valoare strict negativă: dacă obiectul curent (this) este mai mic decât obiectul primit ca
argument;
zero: dacă obiectul curent este egal cu obiectul primit ca argument;
valoare strict pozitivă: dacă obiectul curent este mai mare decât obiectul primit ca
argument.
5
Pentru o ordonare a persoanelor după codul lor intern se procedează astfel:
Interfaţa Comparator
Pentru cazul în care se doreşte o sortare a elementelor unui vector, ce conţine referinţe,
după alt criteriu decât ordinea naturală a elementelor, există o soluţie oferită tot de metoda sort
din clasa java.util.Arrays, dar în varianta în care, pe lângă vectorul ce trebuie sortat, se
transmite un argument de tip Comparator care să specifice modalitatea de comparare a
elementelor.
Interfaţa java.util.Comparator conţine metoda compare, care impune o ordine
totală asupra elementelor unei colecţii. Aceasta returnează un întreg cu aceeaşi semnificaţie ca
la metoda compareTo a interfeţei Comparable şi are următoarea definiţie:
import java.util.*;
class Sortare {
public static void main ( String args []) {
Persoana p[] = new Persoana [4];
p[0] = new Persoana (3, " Ionescu ");
p[1] = new Persoana (1, " Vasilescu ");
p[2] = new Persoana (2, " Georgescu ");
p[3] = new Persoana (4, " Popescu ");
Arrays.sort (p, new Comparator () {
public int compare ( Object o1 , Object o2) {
Persoana p1 = ( Persoana )o1;
Persoana p2 = ( Persoana )o2;
6
return (p1.nume.compareTo(p2.nume ));
}//implementare cu clasa interna anonima
});
System.out.println(" Persoanele ordonate dupa nume :");
for (int i=0; i<p.length ; i++)
System.out.println (p[i]);
}
}
Compararea a două şiruri de caractere se face tot cu metoda compareTo, clasa String
implementând interfaţa Comparable.
Colecţii de obiecte
O colecţie este un obiect care grupează mai multe elemente într-o singură unitate. Prin
intermediul colecţiilor vom avea acces la diferite tipuri de date cum ar fi vectori, liste înlănţuite,
stive, mulţimi matematice, tabele de dispersie, etc.
Colecţiile sunt folosite atât pentru memorarea şi manipularea datelor, cât şi pentru
transmiterea unor informaţii de la o metodă la alta.
Tipul de date al elementelor dintr-o colecţie este Object, ceea ce înseamnă că mulţimile
reprezentate sunt eterogene, putând include obiecte de orice tip.
Colecţiile sunt tratate într-o manieră unitară, fiind organizate într-o arhitectură foarte eficientă şi
flexibilă ce cuprinde:
Interfeţe: tipuri abstracte de date ce descriu colecţiile şi permit utilizarea lor
independent de detaliile implementărilor.
Implementări: implementări concrete ale interfeţelor ce descriu colecţii. Aceste clase
reprezintă tipuri de date reutilizabile.
Algoritmi: metode care efectuează diverse operaţii utile cum ar fi căutarea sau sortarea,
definite pentru obiecte ce implementează interfeţele ce descriu colecţii. Aceşti algoritmi
se numesc şi polimorfici deoarece pot fi folosiţi pe implementări diferite ale unei
colecţii, reprezentând elementul de funcţionalitate reutilizabilă.
Interfeţe de colecţii
Interfeţele reprezintă nucleul mecanismului de lucru cu colecţii, scopul lor fiind de a
permite utilizarea structurilor de date independent de modul lor de implementare. Structura
ierarhică a principalelor interfeţe de colecţii este dată de figura următoare:
7
Collection
Interfaţa Collection modelează o colecţie la nivelul cel mai general, descriind un grup
de obiecte numite şi elementele sale. Unele implementări ale acestei interfeţe permit existenţa
elementelor duplicate, alte implementări nu. Unele au elementele ordonate, altele nu. Platforma
Java nu oferă nici o implementare directă a acestei interfeţe, ci există doar implementări ale
unor subinterfeţe mai concrete, cum ar fi Set sau List.
Obs: Clasa Collections conține metode statice cu algoritmi polimorfici care lucrează cu
colecții (shuffle, sort, copy, fill, revers, rotate etc.).
8
Parcurgerea colecțiilor cu Iterable și Interator
Interfața Iterable definește un mecanism de iterare/traversare a tuturor elementelor dintr-o
colecție printr-un obiect Iterator. Interfața Iterable definește o singură metodă abstractă:
Iterator<T> iterator();
care returnează obiectul Iterator asociat care poate fi folosit pentru parcurgerea tuturor
elementelor din colecție.
Interfața Iterator declară următoarele metode abstracte:
9
Exemplu: Parcurgerea unei colecții.
import java.util.*;
Set
Interfaţa Set modelează noţiunea de mulţime în sens matematic. O mulţime nu poate
avea elemente duplicate. Moşteneşte metodele din Collection, fără a avea alte metode
specifice.
Două dintre clasele standard care oferă implementări concrete ale acestei interfeţe sunt
HashSet şi TreeSet.
SortedSet
Interfaţa SortedSet este asemănătoare cu interfaţa Set, diferenţa principală constând
în faptul că elementele dintr-o astfel de colecţie sunt ordonate ascendent.
Pune la dispoziţie operaţii care beneficiază de avantajul ordonării elementelor.
Ordonarea elementelor se face conform ordinii lor naturale, sau conform cu ordinea dată de un
comparator specificat la crearea colecţiei şi este menţinută automat la orice operaţie efectuată
asupra mulţimii. Singura condiţie este ca, pentru orice două obiecte o1, o2 ale colecţiei, apelul
o1.compareT o(o2) (sau comparator.compare(o1, o2), dacă este folosit un
comparator) trebuie să fie valid şi să nu provoace excepţii.
10
Fiind subclasă a interfeţei Set, moşteneşte metodele acesteia, oferind metode
suplimentare ce ţin cont de faptul că mulţimea este sortată.
public interface SortedSet extends Set {
// Subliste
SortedSet subSet(Object fromElement, Object toElement);
SortedSet headSet(Object toElement);
SortedSet tailSet(Object fromElement);
// Capete
Object first();
Object last();
Comparator comparator();
}
import java.util.Arrays;
import java.util.SortedSet;
import java.util.TreeSet;
// output set
private void printSet( SortedSet< String > set )
{
for ( String s : set )
System.out.printf( "%s ", s );
System.out.println();
} // end method printSet
11
} // end main
} // end class SortedSetTest
List
Interfaţa List descrie liste (secvenţe) de elemente indexate. Listele pot conţine
duplicate şi permit un control precis asupra poziţiei unui element prin intermediul indexului
acelui element. In plus, faţă de metodele definite de interfaţa Collection, avem metode pentru
acces poziţional, căutare şi iterare avansată.
Clase standard care implementează această interfaţă sunt: ArrayList, LinkedList, Vector.
12
// output list contents
for ( int count = 0; count < list.size(); count++ )
System.out.printf( "%s ", list.get( count ) );
if ( collection2.contains( iterator.next() ) )
iterator.remove(); // remove current Color
} // end method removeColors
import java.util.LinkedList;
import java.util.Arrays;
13
public static void main( String args[] )
{
new UsingToArray();
} // end main
} // end class UsingToArray
import java.util.Vector;
import java.util.NoSuchElementException;
public VectorTest()
{
Vector< String > vector = new Vector< String >();
printVector( vector ); // print vector
14
{
if ( vectorToOutput.isEmpty() )
System.out.print( "vector is empty" ); // vectorToOutput is empty
else // iterate through the elements
{
System.out.print( "vector contains: " );
// output elements
for ( String element : vectorToOutput )
System.out.printf( "%s ", element );
} // end else
System.out.println( "\n" );
} // end method printVector
import java.util.Stack;
import java.util.EmptyStackException;
15
{
emptyStackException.printStackTrace();
} // end catch
} // end StackTest constructor
Map
Interfaţa Map descrie structuri de date ce asociază fiecărui element o cheie unică, după
care poate fi regăsit. Obiectele de acest tip nu pot conţine chei duplicate şi fiecare cheie este
asociată la un singur element. Ierarhia interfeţelor derivate din Map este independentă de
ierarhia derivată din Collection.
16
Clase care implementează interfaţa Map sunt HashMap, TreeMap şi Hashtable.
SortedMap
Interfaţa SortedMap este asemănătoare cu interfaţa Map, la care se adaugă faptul că
mulţimea cheilor dintr-o astfel de colecţie este menţinută ordonată ascendent conform ordinii
naturale, sau conform cu ordinea dată de un comparator specificat la crearea colecţiei. Este
subclasa a interfeţei Map, oferind metode suplimentare pentru: extragere de subtabele, aflarea
primei/ultimei chei, aflarea comparatorului folosit pentru ordonare.
import java.util.StringTokenizer;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.TreeSet;
import java.util.Scanner;
public WordTypeCount()
{
map = new HashMap< String, Integer >(); // create HashMap
scanner = new Scanner( System.in ); // create scanner
createMap(); // create map based on user input
displayMap(); // display map content
} // end WordTypeCount constructor
17
// if the map contains the word
if ( map.containsKey( word ) ) // is word in map
{
int count = map.get( word ); // get current count
map.put( word, count + 1 ); // increment count
} // end if
else
map.put( word, 1 ); // add new word with a count of 1 to map
} // end while
} // end method createMap
// sort keys
TreeSet< String > sortedKeys = new TreeSet< String >( keys );
System.out.printf(
"\nsize:%d\nisEmpty:%b\n", map.size(), map.isEmpty() );
} // end method displayMap
Auto-boxing la colecții
O colecție conține doar obiecte nu și elemente de tip primitiv de date. Pentru tipuri primitive
de date se pot folosi vectori, dar aceștia sunt de dimensiune fixă. Pentru a adăuga un element de
tip primitiv într-o colecție trebuie înfășurat (warp) tipul primitiv într-o clasa wrapper, precum
Integer, Double, etc.
18
import java.util.*;
// parcurgere cu iterator
Iterator<Integer> iter = aList.iterator();
while (iter.hasNext()) {
int i = iter.next(); // downcast la Integer de catre compilator,
// autounbox la int, type-safe
System.out.println(i);
}
19