sâmbătă, 3 ianuarie 2026

Relații între obiecte Java

Din definiția Programării Orientate spre Obiecte cunoaștem că acesta este un stil de programare în care programele sunt organizate ca şi colecții de obiecte ce cooperează între ele pentru a realiza funcțiile aplicației. Acestea obiecte cooperează între ele prin intermediul unor relații stabilite de programator.

Există mai multe tipuri de relații între obiecte, iar câteva dintre cele comune sunt:

1. Moștenire. Există între o superclasă și o subclasă, este tipul de relație ”is a” sau ”este un/o”. De exemplu: Angajatul este o Persoana, Ciinele este un Animal, SefDepartament este un Angajat.

Exemplu:

class Angajat{
private String nume;
private String adresa;
private int oreLucrate;

public Angajat(String nume, String adresa, int oreLucrate) {
this.nume = nume;
this.oreLucrate = oreLucrate;
this.adresa = adresa;
}
String getNume(){return nume;}
public void setNume(String nume) { this.nume = nume; }

String getAdresa(){return adresa;}
public void setAdresa(String adresa) { this.adresa = adresa; }

public void setOreLucrate(int oreLucrate) { this.oreLucrate = oreLucrate; }
int getOre(){return oreLucrate;}

public int salariu() { return oreLucrate*20; }
}

class SefDepartament extends Angajat {
public SefDepartament(String nume, String adresa, int oreLucrate) {
super(nume, adresa,oreLucrate); }
public int salariuSef() { return salariu()+1000; }
}

class Test{
public static void main(String[] args) {
System.out.println("---------------------------------------------------");
SefDepartament s = new SefDepartament("Decebal Dumitru", "or. Chisinau", 20);
System.out.println(s.getNume() + " "+ s.getAdresa()+" "+s.getOre()+" "+s.salariuSef());
System.out.println("---------------------------------------------------");
Angajat a = new Angajat("Musteata Victoria", "or. Chisinau", 20);
System.out.println(a.getNume() + " "+ a.getAdresa()+" "+a.getOre()+" "+a.salariu());
}}



2. Agregare. Există între două clase în care nu este relație de moștenire, este tipul de relație ”has a” sau ”are un /o”
Are la bază următorul principiu: o clasă A, face referire la unul sau mai multe obiecte ale unei alte clase B, o modificare produsă în clasa A nu afectează existența instanțelor clasei B. 
Un exemplu de astfel de relație servește relația între clasele Universitate și Student. O universitate poate avea mai mulți studenți, dar studenții pot exista și în afara universității. Un alt exemplu sunt clasele Proiect și MembruEchipa. Deși membrii echipei sunt asociați cu proiectul, aceștia pot exista independent și pot face parte din alte proiecte sau activități. 
Deci o astfel de interacțiune între obiectele unei clase o numim relație de agregare în contextul domeniului IT.

Exemplu:
class Universitate {

private String denumire;
private Student s;

public Universitate (String denumire, Student l) {
this.denumire = denumire;
s = l;
}

public void afiseazaDetalii(){
System.out.println("Denumirea universitatii: "+denumire);
System.out.println("Elevi: ");
System.out.println(s.getNume() + " " + s.getGrupa());
}}

class Student {
private String nume;
private String grupa;

public String getNume() {return nume; }
public void setNume(String nume){ this.nume = nume; }

public String getGrupa() { return grupa;}
public void setGrupa(String grupa){ this.grupa = grupa; }

public Student(String nume, String grupa) {
this.nume = nume;
this.grupa = grupa;
}}

class Test{
public static void main(String[] args) {
Student x = new Student("Victoria","I5413");
Universitate p = new Universitate ("Digitalizare", x);
p.afiseazaDetalii();
}}



Exemplu:
class Universitate {
private String denumire;
private Student [] lista = new Student[2];

public Universitate (String denumire, Student [] l) {
this.denumire = denumire;
lista = l;
}

public void afiseazaDetalii(){
System.out.println("Denumirea universitatii >>>> "+denumire);
System.out.println("Are elevii: ");
for (int i=0; i<lista.length; i++)
System.out.println(lista[i].getNume() + " " + lista[i].getGrupa()); }
}

class Student {
private String nume;
private String grupa;

public String getNume() {return nume; }
public void setNume(String nume) {
this.nume = nume;
}

public String getGrupa() { return grupa;}
public void setGrupa(String grupa) {
this.grupa = grupa;
}

public Student(String nume, String grupa) {
this.nume = nume;
this.grupa = grupa;
}}

class Test{
public static void main(String[] args) {
Student [] lista = new Student[2];
lista[0] = new Student("Victoria","I5413");
lista[1] = new Student("Mihai","I5412");

Universitate p = new Universitate ("Digitalizare", lista);
p.afiseazaDetalii();
}}



3. Compoziție. Similară agregării, dar cu o legătură mai strânsă. O clasă A este compusă din unul sau mai multe obiecte ale unei alte clase B. Dacă clasa A încetează să existe, și clasa B încetează, de asemenea, să existe. Un exemplu de astfel de relație este:
- relația între clasele Casa și Dormitor, dormitorul nu există separat, el face parte dintr-o casă, respectiv dacă dispare casa nu există nici dormitorul.
- relația dintre clasele Laptop și Procesor. Acest component, procesorul, nu există independent de laptop, indicând astfel o relație de compoziție.
- relația între clasele Masina și Motor. Mașina are un motor, cu alte cuvinte motorul este o componentă a mașinii. Dacă mașina va fi distrusă, motorul va fi distrus la fel. Ciclul de viață pentru obiectul Motor este dependent total de ciclul de viață al obiectului Masina:

class Motor {
private String tip;
private int caiPutere;

Motor(String tip, int caiPutere) {
this.tip = tip;
this.caiPutere = caiPutere;
}

public String getTip() { return tip; }

public void setTip(String tip){this.tip = tip; }

public int getPutere() {return caiPutere; }
public void setPutere(int caiPutere){
this.caiPutere = caiPutere;
}}

class Masina {
private String nume;
private Motor motor;

public Masina(String nume) {
this.nume= nume;
this.motor = new Motor("Motorina", 300);
}
public String getNume() { return nume; }
public Motor getMotor() { return motor; }
}

class TestMasina{
public static void main(String[] args) {
Masina masina = new Masina("BMW");

System.out.println("Denumire masina: " +masina .getNume()+ "\n" +"Tip motor: " +masina.getMotor().getTip()+ "\n" + "Cai putere: " +masina.getMotor().getPutere());
}}



Următorul tabel prezintă diferențele între cele trei tipuri de relații între obiecte în context POO:

Caracteristică

Agregare

Compoziție

Moștenire

Definiție

O relație între două clase în care unul dintre obiecte este parte a altuia, dar poate exista independent.

O relație între două clase în care un obiect este format din alt obiect și nu poate exista independent.

O relație între două clase în care o clasă derivată (subclasă) preia caracteristicile și comportamentul unei clase de bază (superclasă).

Dependența ciclului de viață

Obiectul "parte" poate exista independent de obiectul "întreg".

Obiectul "parte" este de obicei creat și distrus împreună cu obiectul "întreg".

O subclasă poate exista independent de superclasă, dar se bazează pe moștenire pentru a împărți caracteristicile superclasei.

Reprezentare

O clasă poate conține o referință la altă clasă, dar fără a controla durata de viață a obiectelor asociate.

O clasă conține direct un alt obiect și controlează durata de viață a obiectelor asociate.

Subclasă extinde sau specializează superclasă, moștenind și adăugând funcționalități noi.

Flexibilitate

Mai flexibilă, deoarece obiectul "parte" poate exista independent și poate fi partajat între mai multe obiecte "întreg".

Mai rigidă, deoarece obiectul "parte" este strâns legat de obiectul "întreg" și nu poate fi partajat ușor între alte obiecte.

Oferă extensibilitate prin adăugarea și modificarea funcționalității în subclasă, dar poate duce la o dependență puternică între subclasă și superclasă.

Exemplu

O universitate are mulți studenți.

Un calculator are o placă de bază, ce are componente precum procesor, memorie etc.

O clasă "Cercetator" derivată dintr-o clasă "Angajat", moștenind atribuțiile și metodele comune angajaților.


Aceste relații sunt foarte importante în programarea orientată pe obiect pentru a crea structuri flexibile, ușor de înțeles și de întreținut. Este important să se adapteze aceste concepte la contextul specific al aplicației sau sistemului pe care îl dezvoltați. Ele facilitează modularitatea, reutilizarea codului și gestionarea complexității în dezvoltarea software-ului.

Succes!
❤️