Documente Academic
Documente Profesional
Documente Cultură
ro/lab/poo
Programare Orientată pe Obiecte
Introducere – informaţii laborator
1.
● Durata: 7 laboratoare X 2 ore
● Punctaj: 30% din nota finală
● Mediu de dezvoltare: JDK 1.5.0
● Sistem de operare: Fedora Core 5
● Toate aplicatiile scrise trebuiesc salvate pe emailul personal
● Aplicatie de laborator: chat clientserver
Introducere în limbajul Java
2.
Java nu este numai un limbaj de programare, Java este o tehnologie care oferă suport dezvoltării
aplicaţiilor distribuite, independente de platformă. Java ca limbaj şi mediu de programare a fost lansat şi este
în continuare sustinut de firma Sun Microsystems. Cea mai mare parte a sintaxei de programare Java este
mostenită de la C++, dar unele din conceptele de programare obiectuală prezente în Java îşi au rădăcinile în
limbajele SmallTalk şi Lisp.
Limbajul Java are câteva caracteristici care îl fac un limbaj de succes pe piaţa actuala de software.
Astfel, limbajul Java poate fi caracterizat ca un limbaj simplu, familiar, robust, orientat pe obiecte,
independent de platforma, adaptat pentru aplicatii distribuite şi care asigură un nivel ridicat de securitate.
Spre deosebire de C++, limbajul Java este în intregime orientat pe obiecte. În orice aplicaţie trebuie
sa existe cel puţin o clasă şi nu se pot defini variabile sau funcţii care să nu aparţină unei clase. În plus, Java
măreste gradul de siguranţă al codului prin existenta a doua nivele de verificare: unul la compilare şi unul la
rulare. Accesul la tablourile Java este verificat la rulare eliminand astfel posibilitatea accesului accidental în
afara domeniului tabloului. Conversiile între tipurile de date sunt restricţionate, evitânduse astfel scrierea
nepermisa a unor zone de memorie.
Programele executabile Java, numite şi bytecodes sunt rezultatul compilării unui program sursă.
Pentru a putea fi executate pe o anumită platformă (Windows, Unix) acestea au nevoie de un emulator Java
Virtual Machine (JVM) specific respectivei platforme. Ca urmare a utilizării emulatorului, un program Java
poate rula pe orice platformă în care se poate executa o masina virtuala Java.
Codul sursa(Hello.java)
Compilare(javac)
Bytecode(Hello.class)
Interpretare/Executie(java)
Native CPU(x86)
poolab1
1 / 10
19.09.06
Programare Orientata pe Obiecte http://arh.pub.ro/lab/poo
O categorie speciala de programe Java o reprezinta categoria appleturilor care sunt programe Java
ce se executa în cadrul unui browser Internet (Netscape Navigator, Internet Explorer, Opera, Firefox).
La baza dezvoltarii unui program Java stă mediul de dezvoltare pus la dispozitie de firma Sun.
Acesta este Java Developers Kit (JDK). Exista medii integrate puternice de dezvoltare, depanare şi testare a
unei aplicatii Java, dar în cadrul laboratorului se vor folosi uneltele standard de programare utilizand mediul
JDK 1.5.0 pus la dispozitie de firma Sun. Mediul JDK este disponibil pe Internet la adresa
http://java.sun.com, freeware, în diverse versiuni şi variante în functie de platforma de lucru (Windows,
Solaris, etc.). Mediul JDK contine pe de o parte o serie de biblioteci de clase Java necesare scrierii unui
program (API) şi pe de alta parte un set de utilitare necesare compilarii, testarii, executiei şi documentarii
unei aplicatii Java. O clasa, un fisier bytecode cu extensia .class, reprezinta unitatea fundamentala a unui
program executabil Java. O biblioteca de clase cuprinde o serie de clase ce au un numitor comun. O astfel de
biblioteca este cunoscuta în Java sub numele de package. JDK include cateva packageuri fundamentale care
contin clase fara de care nu se pot dezvolta aplicatii Java. De exemplu, packageul java.lang contine clasele
fundamentale fara de care un program Java nu poate exista. Acest package este inclus automat de compilator
fara a fi nevoie de precizari suplimentare. Utilizarea unei clase din oricare alt package decat java.lang intrun
program Java se specifica prin directivele:
import nume_package.*;
import nume_package.nume_clasa;
Dintre programele de dezvoltare puse la dispoziţia programatorului amintim:
javac – este compilatorul Java care transforma sursele text scrise în limbaj de programare Java în
cod executabil pe masina virtuala. Fisierul sursa, cu extensia .java se transmite ca şi parametru în programul
javac. Vor rezulta o serie de fisiere cu extensia .class, în functie de numarul de clase definite în fisierul
sursa.
java – este interpretorul Java care executa programele Java (fisierele .class). Este util doar pentru
executia aplicatiilor Java standalone, nu şi a appleturilor. Are ca parametru numele fisierului (fara extensia
.class) rezultat în urma compilarii.
Dezvoltarea şi executia unei aplicatii independente Java
2.1.
Etapele în crearea şi lansarea în executie a unei aplicatii Java sunt: scrierea codului, compilarea,
interpretarea şi lansarea în executie. Editarea unui program Java se poate face utilizand orice editor simplu
de text, care salveaza datele în format text. Se va folosi în laborator utilitarul kate, datorita facilitatilor pe
care le ofera: editarea fisierelor sursa Java, C, C++, HTML, Verilog etc. cu optiuni de highlight a cuvintelor
cheie ale limbajului. Pentru compilare si rulare, se vor folosi comenzile java, respectiv javac din linia de
comanda.
Un exemplu de fisier sursa Java este fisierul Hello.java ce contine urmatoarele linii de cod:
/*
* Programul afiseaza textul “Hello” şi se incheie
*/
public class Hello{
public static void main (String args[]){
System.out.println(“Hello”);
poolab1
2 / 10
19.09.06
Programare Orientata pe Obiecte http://arh.pub.ro/lab/poo
}//end main
}//end class
public static void main(String args[]){
//. . .
}//end main
Aceasta metodă trebuie sa existe în orice aplicatie Java, fiind prima metodă apelată cand se lansează
în executie un program (un bytecode) Java. Termenul public este un cuvant cheie al limbajului Java şi în
acest context indică faptul ca metoda main() este o metoda publică, adică poate fi apelată din orice alta clasa.
Datorită cuvântului cheie static, metoda main() este o metoda legata de clasa Hello şi nu de un obiect, de o
instanta a ei. args[] este un tablou de siruri de caractere (String) şi reprezinta parametrii din linia de
comanda ai programului apelat. In interiorul metodei main se scrie ceea ce se doreste ca programul sa faca,
în acest caz, afişarea sirului Hello. System este o clasa ce contine un membru static out caruia i se poate apela
o metoda println() care are ca parametru şirul care se tipăreşte.
Dacă operaţia de compilare se face cu success (nu apare nici un mesaj de eroare) se obţine un nou
fisier Hello.class, fisier ce contine programul executabil Java.
Structura lexicala a unui program Java
2.2.
Structura şi gramatica unui program Java se aseamana foarte mult cu cea a unui program C++.
Limbajul Java contine urmatoarele unităţi lexicale:
• Comentarii – oferă posibilitatea documentarii programului în vederea unei întelegeri mai uşoare
a programului sursă.
• Cuvinte cheie – sunt cuvinte care au un sens special în limbaj şi insotesc variabilele, metodele,
membrii, clasele etc. Java dispune de urmatoarele cuvinte cheie (keywords):
abstract default if private throw
boolean do implements protected throws
break double import public transient
byte else instanceof return try
case extends int short void
catch final interface static volatile
char finally long super while
class float native switch this
poolab1
3 / 10
19.09.06
Programare Orientata pe Obiecte http://arh.pub.ro/lab/poo
• Identificatorii – sunt şiruri de caractere şi reprezintă numele dat unei variabile, clase sau unei
funcţii. Conditii: şirul începe cu o literă sau caracterul underscore (_); şirul este diferit de orice
cuvânt cheie; şirul este diferit de null, false, true. Deşi nu există o regulă obligatorie pentru
scrierea identificatorilor, există anumite convenţii utilizate: identificatorii numelor de clase încep
cu majusculă, fiecare cuvânt distinct din identificator începe cu majuscula; identificatorii de
variabila încep cu litera mică, fiecare cuvânt care urmează începe cu majusculă; identificatorii
unei funcţii respectă regula de la variabile.
• Literalii – reprezintă valori constante de diferite tipuri de date primitive (întreg, caracter etc).
• Separatorii – sunt utilizati pentru a separa unitătile lexicale unele de altele. Acestia sunt: ( ) { }
[ ] ; , .
• Operatori sunt necesari pentru a realiza operatiile care se aplică asupra unor date din program.
Tipuri de date, Operatori şi Instructiuni
2.3.
Tipurile de date din Java se clasifică în două categorii:
• Tipuri de date primitive – reprezintă acele date care sunt incluse implicit în limbajul Java. Sunt
tipuri numerice intregi (byte, short, int, long, char), tipuri numerice reale (float, double) şi tipul
boolean (boolean).
• Tipuri de date referinţă – sunt clasele, tablourile şi interfeţele. Ca şi în limbajul C++, clasele
reprezintă tipuri generice de date caracterizate printro stare definita de atributele clasei şi printr
o functionalitate definita de metodele clasei; tablourile sunt colecţii de date de acelaşi tip, iar
interfeţele sunt un fel de clase abstacte şi vor fi studiate în lucrarea următoare.
Variabilele de tip primitiv se pot crea numai prin declaraţie (care este în acelaşi timp şi o definiţie).
Variabilele de tip referinţă se pot crea cu operatorul new, care (spre deosebire de C++) returnează o
referinţă. O referinţă Java este un identificator al unui obiect şi este, de fapt un pointer ascuns, asemănător cu
o referinţă C++, de care se deosebeşte în primul rând din punct de vedere sintactic (nu se mai foloseşte
operatorul & la definiţia unei referinţe).
Deoarece nu se pot defini referinţe pentru tipurile primitive, în pachetul java.lang sunt definite mai
multe clase care “împacheteaza” tipurile primitive, adică au ca dată membru o variabilă de tipul primitiv
respectiv. Aceste clase sunt Byte, Short, Integer, Character, Float, Double etc. Majoritatea acestor clase (cu
excepţia claselor Integer şi Character) au aceeaşi denumire ca şi tipul de date primitive corespunzător, cu
primul caracter modificat în majusculă.
Câteva exemple de creare de variabile de tip primitiv şi de tip referinţă sunt date în programul
următor (Numar.java)
// Fisier Numar.java
public class Numar{
int numar;
poolab1
4 / 10
19.09.06
Programare Orientata pe Obiecte http://arh.pub.ro/lab/poo
//
public Numar(int _numar){
numar = _numar;
}//end Numar
//
public static void main(String[] args) {
int _integer = 10;
Integer _integer1 = new Integer(100);
Byte _byte1 = new Byte((byte)20);
Character _character1 = new Character('A');
Numar _numar1 = new Numar(7);
System.out.println("int: " + _integer);
System.out.println("Integer: " + _integer1);
System.out.println("Byte: " + _byte1);
System.out.println("Character: " + _character1);
System.out.println("Numar: " + _numar1.numar);
}//end main
//
}//end class
În acest program se crează o variabilă de tip primitiv (întreg int) prin definiţie (declaraţie) şi mai
multe obiecte de tipul claselor Integer, Byte, Character, Numar, folosind operatorul new. Fiecare variabilă
creată se afişează la consolă folosind funcţia System.out.println(). Clasa Numar este o clasă nouă creată în
program, aşa cum se vede în listing. La execuţia acestui program se obţin următoarele linii afişate la consolă:
poolab1
5 / 10
19.09.06
Programare Orientata pe Obiecte http://arh.pub.ro/lab/poo
class X
class X extends Object
Operatorii Java se pot clasifica în:
• Operatorul de atribuire: =
• Operatori binari: + * / %
• Operatori unari: + ++
• Operatori de comparaţie: == != > >= < <=
• Operatori logici: conditionali && || şi booleeni ! & | ^
• Operatori la nivel de bit: & | ^ ~(complementare) << (deplasare stanga cu semn) >>(deplasare
dreapta cu semn) >>>(deplasare dreapta fara semn)
• Operatori de atribuire combinaţi: aritmetici += = *= /= %= şi la nivel de bit &= |= ^= <<= >>=
>>>=
Operatorul + supraîncărcat pentru clasa String. În Java nu este admisă supraîncărcarea
operatorilor, cu excepţia operatorului de adunare pentru clasa String. Clasa String (din pachetul java.lang)
conţine un şir de caractere şi numeroase metode pentru operaţii asupra acestora. Operatorul de adunare
supraîncărcat pentru clasa String admite trei forme de apel:
sir + var
var + sir
sir1 + sir2
În urma acestei operaţii se obtine un obiect şir de caractere (String) care conţine un şir de caractere
format prin concatenarea celor două subşiruri corespunzătoare celor doi operanzi. Se consideră că operandul
denumit sir (sau sir1, sir2) este o constantă (literal) şir de caractere (de exemplu, “abcde”) sau o referinţă la
un obiect String. În cazul în care variabila var este o referinţă la un obiect, se utilizează metoda toString() a
clasei obiectului (dacă este redefinită în acea clasă) sau metoda toString() moştenită de la clasa Object pentru
a obţine subşirul care intervine în operaţie. Exemple:
String sir1 = ”ABC”, sir2;
int a = 2;
float b=14.32f;
boolean c = true;
Object obj = new Object();
sir2 = sir1 + a;
System.out.println(sir2); // afisare: ABC2
sir2 = ”XYZ” + b;
System.out.println(sir2); // afisare: XYZ14.32
sir2 = sir1 + c;
System.out.println(sir2); // afisare: ABCtrue
sir2 = sir1 + obj;
System.out.println(sir2); // afisare: ABCObject@12123
poolab1
6 / 10
19.09.06
Programare Orientata pe Obiecte http://arh.pub.ro/lab/poo
nume_obiect instanceof nume_clasa
Operatorul instanceof returnează true dacă obiectul (cu referinţa nume_obiect) este o instanţă clasei
nume_clasa sau a unei superclase a acesteia; în caz contrar, returnează false.
Exemple:
Class1 obj1;
Class2 obj2; //Class2 derivata din Class1
Class3 obj3;
boolean test;
test = obj1 instance of Class1; //true
test = obj1 instance of Class2; //true
test = obj1 instance of Class3; //false
Instrucţiunile Java sunt foarte asemănatoare cu instrucţiunile C/C++ şi sunt următoarele: if – else,
switch, for, while, do, break, continue, return. Există două mari diferenţe fată de limbajul C/C++. O
deosebire priveste instrucţunile ce implică expresii conditionale din instructiunile if – else, for, while, do.
Dacă în C aceste expresii puteau fi de tip int, în Java ele trebuie să fie strict de tipul boolean (în Java nu este
posibila conversia din int în boolean). O altă deosebire este legată de instructiunea goto care lipseste în Java
fiind substituita de instructiunile break şi continue care pot primi o eticheta de salt.
Tablouri
2.4.
Un tablou (array) este o listă de elemente de acelaşi tip plasate întro zonă continuă de memorie,
care pot fi adresate utilizând un nume, un identificator comun. Tipul elementelor din tablou trebuie să fie de
acelaşi tip şi poate fi oricare tip primitiv sau tip referinţă.
Un tablou Java este un tip referintă, deci identificatorul (numele) unui tablou reprezinţă o referinţă (o
adresa) la locatia unde se găseste întregul tablou de elemente. Un tablou Java este un obiect care conţine, în
afară de elementele tabloului o variabilă membră publică length din care se poate citi (nu şi scrie)
dimensiunea tabloului.
Tablourile pot fi definite pentru tipuri primitive sau pot conţine referinţe la obiecte (clase).
Tablourile de date primitive conţin chiar acele date memorate în elementele tabloului, iar tablourile de
obiecte (tip referinţă) conţin referinşe memorate în elementele tabloului. Dimensiunile unui tablou sunt fixe
(nu se mai pot modifica după creare).
poolab1
7 / 10
19.09.06
Programare Orientata pe Obiecte http://arh.pub.ro/lab/poo
Prin declararea unui tablou se crează o variabilă referinţă având valoarea null (care nu referă nimic).
Nu se alocă spaţiu pentru elementele tabloului. Forma generală de declarare a unui tablou unidimensional
este:
tip nume_tablou[]; //sau
tip[] nume_tablou;
Exemple:
int[] tabInt;
String tabString[];
Object[] tabObjects;
După declararea unui tablou urmează instantierea lui, adica alocarea zonei de memorie necesară stocarii
elementelor lui. Instanţierea unui tablou se poate face în doua moduri. Cel mai utilizat mod este prin
utilizarea lui new astfel:
nume_tablou = new tip[nr_el];
În acest mod sa alocat o zonă de memorie necesară stocarii unui numar de nr_el, zona care poate fi
adresată prin referinţa nume_tablou. Tot acum se alocă variabila length care va conţine lungimea tabloului
(numărul de elemente ale tabloului). Elementele tabloului conţin datele de tip primitiv sau referinţe la
obiecte şi sunt iniţializate la valori implicite. Elementelor de tip numeric li se va atribuie valoarea 0, celor de
tip boolean valoarea false iar celor de tip referinţă valoarea null.
Un al doilea mod de instanţiere a unui tablou şi care este valabil doar în momentul declaraţiei lui
este următorul:
tip nume[] = {el1, el2, ....elN};
Prin această construcţie se alocă spaţiu elementelor tabloului (la fel ca şi în cazul utilizării
operatorului new) şi se atribuie elementelor valorile specificate în lista de iniţializare (altele decât cele
implicite) elementelor din tablou. Dimeniunea tabloului rezultă din numărul de elemente din lista de
iniţializare. Elementele unui tablou se pot accesa folosind operatorul de indexare ([]).
Exemple:
int[] tabInt = new int[10];
int x = tabInt[2];
long tabLong[] = new long[4];
char tabChar[]={‘t’,‘a’,‘b’,‘l’,‘e’};
Indexul care se foloseşte în operaţia de indexare trebuie să aibă o valoare întreagă pozitivă, cuprinsă
între 0 şi length1. Dacă valoarea indexului nu este pozitivă sau depăşeşte dimensiunea tabloului, în cursul
execuţiei se va “arunca” o excepţie java.lang.ArrayIndexOutOfBoundsException (despre exceptii, in
laboratoarele urmatoare).
Un tablou multidimensional este implementat ca un tablou de tablouri. Pentru a iniţializa un tablou
multidimensional se poate folosi operatorul new sau o listă de initializare la fel ca şi în cazul tabloului
unidimensional.
poolab1
8 / 10
19.09.06
Programare Orientata pe Obiecte http://arh.pub.ro/lab/poo
Exemple:
int [][]tab1;
tab1 = new int[2][3];
int [][]tab2 = {{2,3,4}, {3,4,5}}; // se declara şi se instantiaza
// un tablou bidimensional
int [] tab3[]; // declaratie echivalenta cu int[][] tab3;
Operaţii cu tablouri. În pachetul java.util exitsă clasa Arrays care conţine mai multe metode statice
care pot fi apelate pentru operaţii asupra elementelor din tablouri. Câteva dintre aceste metode sunt:
• fill(tip[], val), pentru umplerea unui tablou de date de tipul tip cu valoarea val (de acelaşi tip
dat). Există mai multe vesiuni supraîncărcate, pentru tipuri primitive şi pentru referinţe (la clasa
de bază Object): fill(int[] a, int v), fill(Object[] a, Object v).
• equals(tip[] a, tip[] v), returnează true dacă cele două tablouri (de date de acelaşi tip) au toate
elementele egale.
• sort(tip[] a), sortează elementele vectorului a (care conţine elemente de tipul tip).
Conventii de scriere a codului
3.
La laboratorul de POO se va puncta si modul in care un program este paginat, tabulat, modul in care sunt
denumite calsele, metodele si variabilele si in general modul in care codul este structurat. Regulile care
trebuie respectate sunt:
● Întrun fişier Java se defineste o singura clasă.
● Segmentele fişierului apar în următoarea ordine:
■ Comentariul de introducere (header)
■ Declaraţia de pachet
■ Directivele de import
■ Declaraţia de clasă / interfaţă
■ Declaraţiile de câmpuri: ale clasei (statice), ale instanţei, constante( toate identate cu
un tab).
■ Constructori, de la cel mai puţin complex la cel mai complex( neidentate)
■ Metode( neidentate)
■ Comentariul de final (footer)
● Toate segmentele fişierului sunt despărţite printro liniecomentariu ce apare inclusiv între
constructori şi între metode.
● Metoda main, dacă există, este plasată între constructori şi metode.
● Pentru instrucţiuni if / dowhile / for / case, şi pentru blocul metodelor, acolada care
deschide blocul de instrucţiuni se află pe aceeaşi linie cu instrucţiunea / declaraţia iniţială iar acolada
de final se află pe o linie separată, pe aceeaşi coloana cu prima literă din instrucţiune / declaraţie. De
exemplu:
if(numar == 3){
//... do something...
}
poolab1
9 / 10
19.09.06
Programare Orientata pe Obiecte http://arh.pub.ro/lab/poo
● Un bloc de instrucţiuni este identat cu un tab faţă de nivelul imediat superior.
● Numele de clase, implicit constructori, încep cu majusculă. De exemplu: NumeClasa.
● Numele de metode încep cu litera mică. De exemplu: numeMetoda.
● Numele de cămpuri încep cu litera mică. De exemplu: numeCamp.
● Numele de constante sunt scrise numai cu majuscule, cuvintele fiind desparţite prin “_” . De
exemplu: TYPE_ERROR.
● Argumentele si variabilele locale ale metodelor sunt declarate imediat sub declaraţia
metodei, neidentate, şi încep cu caracterul “_”, având a doua literă mică. Excepţie fac contorii de
cicluri: i, j, k.
● Numele trebuie să fie cât mai sugestive în ceea ce priveşte scopul lor, pentru a evita
comentariile excesive.
Aceste conventii de scriere a codului sunt doar un minim necesar(si obligatoriu) pentru laboratorul de POO.
Pentru cei ce vor sa cunoasca tot setul de conventii de scriere a codare recomandat de Sun Microsystems il
pot gasi la adresa: http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html
Referinte
4.
4.1. Kevin Taylor, Java Programming Tutorial,
http://java.about.com/od/beginningjava/a/beginjavatutor.htm
4.2. Bruce Eckel, Thinking in Java, 3rd ed. Revision 4.0,
http://arh.pub.ro/mirrors/eckelbooks/TIJ3/TIJ3.htm
4.3. Sun Microsystems, The Java™ Tutorials,
http://java.sun.com/docs/books/tutorial/java/TOC.html
Exercitii
5.
5.1. Sa se scrie o clasa Mesaj care sa abstractizeze notiunea de scrisoare postala. Clasa Mesaj ar
trebui sa contina campuri pentru destinatar, expeditor si continutul mesajului.
5.2. Sa se scrie o fuctie afiseazaMesaj() apartinand clasei Mesaj care sa afiseze la consola toate
informatiile continute de mesaj.
5.3. Sa se scrie o functie main care sa instantieze aceasta clasa Mesaj cu diferite valori si sa se
apeleze pentru fiecare instanta functia afiseazaMesaj().
poolab1
10
/ 10
19.09.06