Clasa si obiect, concepte de baza
Cuprins
Clasa și Obiect
Clasa
Clasa este un șablon sau o structură care definește:
Atributele (variabilele)
Comportamentul (metodele)
Clasa reprezintă conceptul abstract al unui tip de obiect, definind structura și comportamentul obiectelor care vor fi create bazate pe această clasă.
public class Student {
// Atribute
private String nume;
private int varsta;
// Constructor
public Student(String nume, int varsta) {
this.nume = nume;
this.varsta = varsta;
}
// Metode
public void studiere() {
System.out.println(nume + " studiază");
}
}
Obiect
Obiectul este o instanță a unei clase. Reprezintă implementarea concretă a unui șablon definit de clasă.
// Crearea unui obiect de tip Student
Student student1 = new Student("Ion", 20);
Student student2 = new Student("Maria", 21);
// Apelarea metodelor obiectului
student1.studiere(); // Output: Ion studiază
student2.studiere(); // Output: Maria studiază
Constructori
Constructorii sunt metode speciale care sunt apelate automat la crearea unui obiect și sunt folosite pentru:
Inițializarea atributelor
Alocarea resurselor necesare
Caracteristici:
Au același nume ca și clasa
Nu au tip de retur, nici măcar
void
Pot fi supraîncărcați (overloaded)
public class Carte {
private String titlu;
private String autor;
private int anPublicatie;
// Constructor implicit
public Carte() {
titlu = "Necunoscut";
autor = "Anonim";
anPublicatie = 2000;
}
// Constructor cu parametri
public Carte(String titlu, String autor) {
this.titlu = titlu;
this.autor = autor;
this.anPublicatie = 2000; // valoare implicită
}
// Constructor cu toți parametrii
public Carte(String titlu, String autor, int anPublicatie) {
this.titlu = titlu;
this.autor = autor;
this.anPublicatie = anPublicatie;
}
}
Atribute
Atributele sunt variabilele definite într-o clasă, reprezentând starea sau datele unui obiect.
public class Persoana {
// Atribute
private String nume; // atribut de instanță
private String prenume; // atribut de instanță
private int varsta; // atribut de instanță
private static int numarPersoane; // atribut static (de clasă)
private final String CNP; // atribut constant (final)
// Constructor
public Persoana(String nume, String prenume, int varsta, String CNP) {
this.nume = nume;
this.prenume = prenume;
this.varsta = varsta;
this.CNP = CNP;
numarPersoane++;
}
}
Clasificarea atributelor:
Atribute de instanță: aparțin fiecărui obiect și pot avea valori diferite pentru fiecare instanță
Atribute statice (de clasă): aparțin clasei, nu instanțelor; sunt comune pentru toate obiectele de acel tip
Atribute finale (constante): nu pot fi modificate după inițializare
Metode
Metodele definesc comportamentul unui obiect și reprezintă acțiunile pe care obiectul le poate executa.
public class Calculator {
// Atribute
private double rezultat;
// Metode
public void aduna(double a, double b) {
rezultat = a + b;
}
public void scade(double a, double b) {
rezultat = a - b;
}
public double getRezultat() {
return rezultat;
}
// Metodă statică
public static double patrat(double numar) {
return numar * numar;
}
}
Clasificarea metodelor:
Metode de instanță: aparțin fiecărui obiect și pot accesa atributele și alte metode ale instanței
Metode statice (de clasă): aparțin clasei, nu instanțelor; nu pot accesa atributele non-statice sau metodele de instanță
Metode finale: nu pot fi suprascrise în subclase
Convenții Java
Convenții de numire
Java folosește următoarele convenții de numire:
Clase:
Substantive
CamelCase cu prima literă mare (PascalCase)
Exemple:
Student
,ContBancar
,GestiuneAngajati
Atribute și Metode:
Verbe pentru metode (acțiuni)
camelCase cu prima literă mică
Exemple:
nume
,adresaEmail
,calculeazaSalariu()
Constante:
Toate literele majuscule, cu subliniere între cuvinte
Exemple:
MAX_SIZE
,PI
,DATABASE_URL
Pachete:
Toate literele mici
De obicei folosește domeniul inversat (ex:
org.example.proiect
)Exemple:
java.util
,com.companie.proiect
Bune practici
Numele ar trebui să fie descriptive și să indice scopul
Evitați abrevierile ambigue
Folosiți pluralul pentru colecții (ex:
List<Student> studenti
)Utilizați prefixe pentru variabile boolean:
is
,has
,can
(ex:isActive
,hasChildren
)
Cuvinte Cheie
new
Cuvântul cheie new
este utilizat pentru a instanția un obiect (a crea o instanță a unei clase).
// Sintaxă: TipClasa numeVariabila = new TipClasa(parametri);
String text = new String("Hello World");
ArrayList<Integer> numere = new ArrayList<>();
Student student = new Student("Ana", 22);
Procesul când se folosește new
:
Se alocă memorie pentru noul obiect
Se apelează constructorul clasei
Se returnează o referință către obiectul nou creat
null
null
reprezintă o valoare specială care indică faptul că o variabilă de tip referință nu referă niciun obiect.
// Declararea unei variabile fără a o inițializa
Student student; // valoarea implicită este null
// Atribuirea explicită a valorii null
String mesaj = null;
// Verificarea pentru null
if (mesaj == null) {
System.out.println("Mesajul este null!");
}
Pericole:
Apelarea metodelor pe o referință
null
genereazăNullPointerException
Este considerată o bună practică verificarea valorilor pentru
null
înainte de a le utiliza
this
Cuvântul cheie this
se referă la obiectul curent (instanța curentă a clasei).
Utilizări:
Rezolvarea ambiguității între atributele clasei și parametrii metodei/constructorului:
public class Persoana {
private String nume;
public Persoana(String nume) {
this.nume = nume; // this.nume se referă la atributul clasei
}
}
Apelarea unui alt constructor din același clasă:
public class Persoana {
private String nume;
private int varsta;
public Persoana() {
this("Necunoscut", 0); // Apelează celălalt constructor
}
public Persoana(String nume, int varsta) {
this.nume = nume;
this.varsta = varsta;
}
}
Pentru returnarea obiectului curent (permite înlănțuirea metodelor):
public class Builder {
private int valoare;
public Builder adauga(int x) {
valoare += x;
return this; // Returnează obiectul curent
}
public Builder scade(int x) {
valoare -= x;
return this;
}
}
// Utilizare:
Builder b = new Builder();
b.adauga(5).scade(2).adauga(10); // Înlănțuire de metode
static
Cuvântul cheie static
este folosit pentru a declara membri (atribute sau metode) care aparțin clasei înseși, nu instanțelor individuale.
Atribute statice:
Sunt comune tuturor instanțelor clasei
Sunt inițializate o singură dată, la încărcarea clasei
Pot fi accesate direct prin numele clasei
public class Contor {
private static int numar = 0; // atribut static
public Contor() {
numar++; // incrementat la fiecare instanțiere
}
public static int getNumar() { // metodă statică
return numar;
}
}
// Utilizare:
Contor c1 = new Contor();
Contor c2 = new Contor();
System.out.println(Contor.getNumar()); // Output: 2
Metode statice:
Nu pot accesa atribute non-statice sau metode non-statice direct
Nu pot utiliza cuvântul cheie
this
Pot fi apelate direct prin numele clasei fără a crea o instanță
Exemple comune:
Math.sqrt()
,Arrays.sort()
,Collections.sort()
final
Cuvântul cheie final
poate fi aplicat variabilelor, metodelor și claselor pentru a impune restricții.
Variabile finale (constante):
Nu pot fi modificate după inițializare
Trebuie inițializate la declarare sau în constructor
public class Constante {
final int MAX_UTILIZATORI = 100; // inițializat la declarare
final String PREFIX;
public Constante(String prefix) {
this.PREFIX = prefix; // inițializat în constructor
}
}
Metode finale:
Nu pot fi suprascrise în subclase
public class Parinte {
public final void metodaFinala() {
// implementare care nu poate fi modificată în subclase
}
}
Clase finale:
Nu pot fi extinse (nu pot avea subclase)
Exemple:
String
,Integer
,Math
public final class ClasaFinala {
// Această clasă nu poate fi extinsă
}
Supraîncărcarea Metodelor
Supraîncărcarea metodelor (method overloading) este abilitatea de a defini mai multe metode cu același nume dar cu parametri diferiți în aceeași clasă.
Criteriile pentru supraîncărcarea metodelor:
Trebuie să difere prin numărul parametrilor și/sau
Trebuie să difere prin tipul parametrilor
Tipul de retur NU este luat în considerare pentru determinarea supraîncărcării.
public class Calculator {
// Supraîncărcarea metodei de adunare
// Versiunea pentru două numere întregi
public int aduna(int a, int b) {
return a + b;
}
// Versiunea pentru trei numere întregi
public int aduna(int a, int b, int c) {
return a + b + c;
}
// Versiunea pentru două numere reale
public double aduna(double a, double b) {
return a + b;
}
// Versiunea pentru un număr întreg și unul real
public double aduna(int a, double b) {
return a + b;
}
}
Avantajele supraîncărcării metodelor:
Îmbunătățește lizibilitatea și reutilizarea codului
Permite utilizarea aceluiași nume pentru operații similare
Metodele pot fi apelate cu tipuri diferite de parametri
Compararea Obiectelor
În Java, există două metode principale pentru a compara obiecte:
Operatorul
==
compară referințele (dacă două variabile referă același obiect)Metoda
equals()
compară conținutul obiectelor (valorile)
Metoda equals()
Semnătură: public boolean equals(Object obj)
Este moștenită din clasa
Object
Implementarea implicită compară referințele (identic cu
==
)Pentru compararea corectă a conținutului, trebuie suprascrisă
public class Persoana {
private String nume;
private String CNP;
public Persoana(String nume, String CNP) {
this.nume = nume;
this.CNP = CNP;
}
// Getteri și setteri
// Suprascriere metoda equals
@Override
public boolean equals(Object obj) {
// Verificare dacă obiectul este aceeași instanță
if (this == obj) {
return true;
}
// Verificare dacă obiectul este null sau de alt tip
if (obj == null || getClass() != obj.getClass()) {
return false;
}
// Conversie la tipul corect
Persoana altaPersoana = (Persoana) obj;
// Compararea atributelor relevante
return CNP != null && CNP.equals(altaPersoana.CNP);
}
// De obicei, hashCode() este suprascrisa împreună cu equals()
@Override
public int hashCode() {
return CNP != null ? CNP.hashCode() : 0;
}
}
Reguli pentru implementarea corectă a metodei equals()
:
Reflexivitate: Pentru orice obiect
x
,x.equals(x)
trebuie să returnezetrue
Simetrie: Pentru orice obiect
x
șiy
, dacăx.equals(y)
returneazătrue
, atunciy.equals(x)
trebuie să returnezetrue
Tranzitivitate: Pentru orice obiecte
x
,y
șiz
, dacăx.equals(y)
șiy.equals(z)
returneazătrue
, atuncix.equals(z)
trebuie să returnezetrue
Consistență: Pentru orice obiecte
x
șiy
, apeluri multiple alex.equals(y)
trebuie să returneze constanttrue
saufalse
, presupunând că nu s-a modificat nicio informațiePentru orice obiect non-null
x
,x.equals(null)
trebuie să returnezefalse
Notă: Când suprascriezi equals()
, ar trebui să suprascrii și hashCode()
pentru a menține contractul hashCode-equals.
Specificatori de Acces
Specificatorii de acces controlează vizibilitatea (accesibilitatea) claselor, atributelor, metodelor și constructorilor.
public
Da
Da
Da
Da
protected
Da
Da
Da
Nu
default
Da
Da
Nu
Nu
private
Da
Nu
Nu
Nu
public
Accesibil din orice loc
Utilizat pentru interfețe publice și clase care vor fi folosite de alte pachete
public class ContBancar {
public void depunere(double suma) {
// Metodă accesibilă din orice loc
}
}
protected
Accesibil în același pachet și în subclase (chiar dacă subclasele sunt în alte pachete)
Permite subclaselor să acceseze și să suprascrie membri
public class Animal {
protected void respira() {
// Accesibil în același pachet și în subclase
}
}
default (fără specificator)
Accesibil doar în același pachet
Se numește și "package-private"
class Helper {
void ajuta() {
// Accesibil doar în același pachet
}
}
private
Accesibil doar în interiorul clasei
Cel mai restrictiv nivel de acces
Utilizat pentru detalii de implementare
public class Utilizator {
private String parola;
private void schimbaParola(String parolaNoua) {
// Accesibil doar în interiorul clasei
this.parola = parolaNoua;
}
}
Garbage Collector
Garbage Collector (GC) este un proces automat în Java care:
Identifică și elimină obiectele care nu mai sunt referite (inaccesibile)
Eliberează memoria ocupată de acestea
Rulează automat, fără intervenția programatorului
Cum funcționează Garbage Collector
Identifică obiectele care nu mai sunt referite de nicio variabilă accesibilă
Apelează metoda
finalize()
(dacă este suprascrisă) înainte de ștergerea obiectuluiEliberează memoria ocupată de obiect
Demonstrarea Garbage Collector-ului
public class DemoGC {
private String nume;
public DemoGC(String nume) {
this.nume = nume;
System.out.println("Obiect creat: " + nume);
}
@Override
protected void finalize() {
System.out.println("Obiect eliminat: " + nume);
}
public static void main(String[] args) {
// Crearea obiectelor
DemoGC obj1 = new DemoGC("Obiect 1");
DemoGC obj2 = new DemoGC("Obiect 2");
// Eliminarea referințelor
obj1 = null; // Obiect 1 devine eligibil pentru GC
// Sugeram Garbage Collector să ruleze
System.gc();
// Așteptăm puțin pentru a vedea efectele
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Program terminat");
}
}
Notă: Apelarea System.gc()
doar sugerează JVM să ruleze GC, dar nu garantează că va rula imediat sau că va colecta toate obiectele nereferenciate.
Exemple
Pentru a testa o parte din conceptele de mai sus incarcati in IDE urmatorul proiect Java: exemple-curs-2-oop
Last updated