Ce face Clase și obiecte (class)
O clasă este un „șablon”: spune ce date are un lucru (câmpurile) și ce poate face (metodele). Cuvântul cheie class declară clasa. Un obiect este un exemplar concret construit după șablon cu new: clasa Elev este una singură, dar poți avea mii de obiecte Elev, fiecare cu numele și nota lui.
Câmpurile fără static aparțin fiecărui obiect în parte. Le accesezi cu punct: e.nume, iar metodele le apelezi la fel: e.afiseaza(). În interiorul clasei, o metodă vede direct câmpurile obiectului pe care a fost apelată.
Variabila de tip clasă nu conține obiectul, ci o referință către el. Dacă scrii Elev b = a;, ambele variabile arată spre același obiect, iar o modificare făcută prin b se vede și prin a. Orice clasă moștenește din Object metode precum toString(), pe care le poți rescrie.
Exemple
Exemplul 1: O clasă cu câmpuri și metode
Fiecare obiect are propriile valori în câmpuri. Metoda promovat() folosește câmpul nota al obiectului pe care a fost apelată.
class Elev {
String nume;
String oras;
double nota;
boolean promovat() {
return nota >= 5;
}
void afiseaza() {
System.out.println(nume + " (" + oras + "): " + nota + (promovat() ? " - promovat" : " - corigent"));
}
}
public class Main {
public static void main(String[] args) {
Elev ana = new Elev();
ana.nume = "Ana";
ana.oras = "Iași";
ana.nota = 9.5;
Elev radu = new Elev();
radu.nume = "Radu";
radu.oras = "Cluj";
radu.nota = 4.25;
ana.afiseaza();
radu.afiseaza();
}
}
Rezultat
Ana (Iași): 9.5 - promovat
Radu (Cluj): 4.25 - corigent
Exemplul 2: Două variabile, același obiect
copie = cont copiază doar referința, nu obiectul. Depunerea făcută prin copie modifică același cont. Pentru un obiect nou ai nevoie de încă un new.
class Cont {
String titular;
double sold;
void depune(double suma) {
sold += suma;
}
}
public class Main {
public static void main(String[] args) {
Cont cont = new Cont();
cont.titular = "Maria";
cont.sold = 100;
Cont copie = cont; // aceeași referință
copie.depune(50);
System.out.println("cont.sold = " + cont.sold);
System.out.println("același obiect? " + (cont == copie));
Cont altul = new Cont(); // obiect nou
altul.titular = "Maria";
altul.sold = 150;
System.out.println("altul == cont? " + (altul == cont));
}
}
Rezultat
cont.sold = 150.0
același obiect? true
altul == cont? false
Exemplul 3: toString() pentru afișare
Fără toString(), println afișează ceva de forma Produs@1b6d3586 (numele clasei și un cod hash). Rescriind metoda moștenită din Object, alegi tu textul.
class Produs {
String denumire;
double pret;
@Override
public String toString() {
return denumire + " - " + pret + " lei";
}
}
public class Main {
public static void main(String[] args) {
Produs p = new Produs();
p.denumire = "Cozonac";
p.pret = 32.5;
System.out.println(p);
System.out.println("În coș: " + p);
}
}
Rezultat
Cozonac - 32.5 lei
În coș: Cozonac - 32.5 lei
Greșeli frecvente
- Folosești un obiect neconstruit:
Elev e = null; e.afiseaza();aruncăNullPointerException. O variabilă locală neinițializată nici nu compilează (variable e might not have been initialized). - Crezi că
b = acopiază obiectul. Copiază doar referința; ambele variabile arată spre același obiect. - Compari obiecte cu
==. Operatorul verifică dacă este același obiect, nu dacă au aceleași valori. Pentru conținut foloseșteequals(vezi pagina equals și hashCode).
Comenzi înrudite
new: new creează un obiect nou (sau un array) în memorie, apelează constructorul și returnează referința către el.Constructori: Constructorul are numele clasei, nu are tip returnat și pregătește obiectul nou; o clasă poate avea mai mulți constructori.this: this este referința către obiectul curent: deosebește câmpurile de parametri, apelează alt constructor sau returnează obiectul.Modificatori de acces (public, protected, private): public, protected, private și lipsa modificatorului stabilesc cine poate vedea o clasă, un câmp, o metodă sau un constructor.equals și hashCode: equals decide când două obiecte sunt „egale” ca valoare; hashCode trebuie rescris împreună cu el, altfel HashMap și HashSet nu funcționează corect.record: record declară o clasă imutabilă pentru date: constructorul, accesorii, equals, hashCode și toString sunt generați automat.