Se afișează postările cu eticheta override. Afișați toate postările
Se afișează postările cu eticheta override. Afișați toate postările

duminică, 8 februarie 2026

Polimorfism static și dinamic. Set de probleme

Repere teoretice: https://musteatadidactic.blogspot.com/2026/02/polimorfism-supraincarcarea-si.html

1. Deschideți editorul de cod Java și rulați Exemplul 1 din partea teoretică. Apoi realizați următoarele:
  • Adăugați o clasă Test în care instanțiați clasa Elev folosind toți constructorii.
  • Supraîncărcați constructorul pentru un parametru de tip int.
  • Testați funcționalitatea noului constructor supraîncărcat.
2. Deschideți editorul de cod Java și rulați Exemplul 3 din partea teoretică. Apoi realizați următoarele:
  • Instanțiați clasa Operații în metoda main() și testați metodele programate.
  • Supraîncărcați metoda suma() pentru un vector de elemente de tip int.
  • Supraîncărcați metoda suma() pentru 2 parametri de tip double.
  • Testați în metoda main() noile funcționalități.
3. Deschideți editorul de cod Java și rulați Exemplul 2 din partea teoretică. Apoi realizați următoarele:
  • Creați o clasă Test, în care să instanțiați clasa Manager și să verificați funcționarea metodei de calcul al salariului.
  • Definiți o clasă nouă Instructor, care extinde clasa Angajat și include o nouă caracteristică, nocivitate, care este un adaos fix pentru condiții de muncă nocive.
  • Supradefiniți în clasa Instructor metoda salariu(), astfel încât să includă în calcule și nocivitatea.
  • Supradefiniți în clase metoda toString().
  • Testați în metoda main() noua clasă.
  • Adăugați clasei Angajat constructor fără parametri.
  • Supraîncărcați constructorul clasei Angajat astfel încât acesta să inițializeze caracteristicele clasei.
  • Creați constructorul parametrizat al clasei Manager.
  • Adăugați o nouă clasă ConducatorAuto care va extinde clasa Angajat. Despre un conducător auto se cunoaște că are suplimentar la salariu o anumită sumă x, pentru că nu are zile de odihnă, și o altă sumă y, ce reprezintă plata pentru combustibil.
  • Creați constructorul parametrizat al clasei ConducatorAuto.
  • Supraîncărcați metoda int salariu() din superclasă, astfel încât la calculul salariul de bază să se ia în considerare și cele două adaosuri ale conducătorului auto.
  • Instanţiați clasa ConducatorAuto în clasa Test.
  • Adăugați metodei main() din clasa Test o listă statică de obiecte de tip Angajat. Încărcați în listă obiecte de tip Manager, Instructor și ConducatorAuto.
  • Adăugați clasei Test o metodă statică care va primi ca parametru o listă de tip Angajat și care va afișa elementele listei la ecran.
  • Apelați metoda pentru lista de angajați.
  • Adăugați clasei Test o metodă statică care va primi ca parametru o listă de tip Angajat și care va afișa la ecran angajatul cu cel mai mare salariu.
  • Testați funcționalitatea metodei pentru lista de angajați.
4. Compuneți un proiect Java ce va conține:
  • clasa Persoana definită de următoarele atribute: nume, prenume, idnp (codul personal de 13 cifre) și metode: constructorul clasei, afişare().
  • clasa Student, derivata clasei Persoana. Pentru clasa Student vor fi adăugate:
    • date: media notelor curente, grupa;
    • metode: constructorul clasei, va fi supradefinită metoda afişare(), bursa(). Bursa va fi determinată conform formulei: media*75 lei, dacă media este mai mare decât 7.5, în caz contrar va fi 0.
  • clasa Salariat, derivata clasei Persoana. Pentru clasa Salariat vor fi adăugate:
    • date: numărul de ore lucrate, plata pentru o oră, anul angajării;
    • metode: constructorul clasei, va fi redefinită metoda afişare(), salariu(). Salariul va fi determinat conform formulei: nr_ore*plata.
  • clasa Angajat_calificat, derivata clasei Salariat. Pentru clasa Angajat_calificat vor fi adăugate:
    • date: gradul calificării (1 superior, 2 mediu, 3 inferior);
    • metode: vor fi redefinite metodele afişare() și salariu(). Salariu va fi determinat conform formulei: nr_ore*plata*(100%+calificare).
  • clasa TestStudentiAngajați:
    • instanțiați o listă de 5 studenți.
    • adăugați o metodă care va primi ca parametru lista de obiecte de tip Student și va afișa numărul de studenți dintr-o grupă anumită.
    • testați această metodă pentru lista instanţiată.
    • adăugați o metodă care va primi ca parametru lista de obiecte de tip Student și va afișa studentul cu bursa minimă.
    • testați această metodă pentru lista instanţiată.
    • instanțiați o listă de 5 salariați.
    • instanțiați o listă de 5 studenți.
    • adăugați o metodă care va primi ca parametru lista de obiecte de tip Salariat și va afișa datele despre salariatul cu salariu minim.
    • Testați noile funcționalități.
  • Ce sugestii aveți pentru îmbunătățirea performanței codului?
Succes! 
❤️

sâmbătă, 7 februarie 2026

Polimorfism. Supraîncârcarea și supradefinirea metodelor

Polimorfismul este, după cum deja bine cunoaștem, unul dintre cele patru principii fundamentale ale Programării Orientate pe Obiecte. Deviza sa este: „Același nume – implementare diferită”.
În programare, polimorfismul se referă la capacitatea unui obiect sau a unei metode de a se comporta în moduri diferite, în funcție de context.
O analogie din viața reală ar fi mașina: aceeași mașină poate fi folosită pentru transportul de persoane, pentru transportul de mărfuri sau pentru curse. Deși vorbim despre o singură entitate, care este mașina, aceasta poate îndeplini mai multe funcții.
Un exemplu mai tehnic îl reprezintă forme geometrice. O clasă Forma poate avea o metodă arie(), însă clasele derivate, precum Triunghi sau Cerc, vor calcula aria în mod diferit, în funcție de proprietățile lor specifice acestora.

În funcție de momentul în care se decide care metodă va fi executată, polimorfismul se clasifică în:
1. Polimorfism Static (Early Binding)
- Se realizează la compilare.
- Compilatorul știe exact ce metodă să apeleze verificând semnătura, adică numele și parametrii acesteia.
- Se implementează prin Supraîncărcarea metodelor (Overloading).
- Atunci când supraîncărcăm metode într-o clasă, compilatorul alege ce metodă să fie apelată în funcție de numărul, tipul și ordinea parametrilor transmiși.
2. Polimorfism Dinamic (Late Binding)
- Se realizează la execuție (runtime).
- Decizia privind metoda apelată se ia în funcție de tipul obiectului creat efectiv în memorie, nu de tipul referinței.
- Se implementează prin Supradefinirea metodelor (Overriding) și este strâns legat de conceptul de Moștenire.

Supraîncărcarea metodelor se referă la definirea a două sau mai multe metode în aceeași clasă cu același nume, dar cu liste diferite de parametri.
Deci, metodele supraîncărcate:
- Trebuie să conțină nume identic
- Trebuie să aibă listă de argumente diferită (număr de argumente și tip diferit)
- Pot avea tip de return diferit
- Pot avea diferiți modificatori de acces
- Pot arunca diferite tipuri de excepții

În următoarele exemple vom studia cum și în ce contexte putem utiliza supraîncărcarea metodelor.

Exemplul 1. Supraîncărcarea constructorului.
class Elev {
private String nume, prenume;
private int virsta;
public Elev() {
}
public Elev(String nume, String prenume) {
this.nume = nume;
this.prenume = prenume;
}
public Elev(String nume, String prenume, int virsta) {
this.nume = nume;
this.prenume = prenume;
this.virsta = virsta;
}

Exemplul 2. Supraîncărcarea unei metode din clasa părinte în clasa copil.
class Angajat{
protected String nume, prenume;
protected int nrOre, plataOra;
int salariu() {
return nrOre*plataOra;
}
}
class Manager extends Angajat {
int salariu(int adaos) {
return nrOre*plataOra+adaos;
}}

Exemplul 3. Supraîncărcarea unei metode pentru număr diferit de parametri, în interiorul aceleiași clase:
class Operatii{
int suma(int a, int b){
return a+b;
}
int suma(int a, int b, int c){
return a+b+c;
}
int suma(int a, int b, int c, int d){
return a+b+c+d;
}}

Exemplul 4. Supraîncărcarea unei metode pentru parametri cu tip diferit, în interiorul aceleiași clase:
class Operatii{
int suma(int a, int b){
return a+b;
}
double suma(double a, double b){
return a+b;
}
double suma(int a, double b, int c){
return a+b+c;
}}

Reţineţi !

1. Dacă vom supraîncărca metode cu aceeași listă de parametri, dar tip de return diferit vom obține eroare de compilare, aceasta nu oferă suficientă informație compilatorului pentru a face diferență.

2. Metodele statice, private și finale pot fi supraîncărcate.


Supradefinirea reprezintă o formă de polimorfism prin care o subclasă oferă o implementare proprie pentru o metodă moștenită de la superclasă. 
Metoda supradefinită (suprascrisă) trebuie să aibă aceeași semnătură (nume, tip de returnare și lista de parametri) ca și metoda moștenită. Orice modificare a semnăturii în subclasă va duce la o eroare de compilare.
Este tip de polimorfism dinamic deoarece la faza de execuție este selectată metoda corespunzătoare, în funcție de tipul real al obiectului. 
Exemplele ce urmează sunt exemple de supraefinire a metodelor.

Exemplul 5. Supradefinirea metodei run().
class Vehicul {
void run(){
System.out.println("Vehiculul merge !");
}}

class Bicicleta extends Vehicul {
void run(){
System.out.println("Bicicleta merge !");
}}

class TestAutomobile {
public static void main(String[] args) {
Vehicul v1 = new Vehicul();
Bicicleta b1 = new Bicicleta();
Vehicul c1 = new Bicicleta(); //detalii
v1.run();
b1.run();
c1.run();
}}
Rețineți !
1. Numai metodele moștenite pot fi supradefinite.
2. Metodele supradefinite trebuie să conţină același nume, aceeaşi listă de parametri şi acelaşi tip de return altfel nu merge vorba de supradefinire.
3. Metodele de tip private, final, static şi constructorii nu pot fi supradefiniţi.
4. O metoda supradefinită nu trebuie să conțină un modificator de acces mai restrictiv decât metoda originală din clasa părinte:
- Dacă metoda originală are modificatorul implicit, metoda supradefinită poate avea unul din modificatorii: implicit, protected sau public.
- Dacă metoda originală are modificatorul protected, metoda supradefinită poate avea unul din modificatorii: protected sau public.
- Dacă metoda originală are modificatorul public, metoda supradefinită poate avea doar modificatorul public.
5. Adăugarea anotării @Override deasupra metodei suprascrise este o practică bună, deoarece ajută la identificarea erorilor de supradefinire în timpul compilării. Dacă metoda nu respectă criteriile de supradefinire, compilatorul va genera o eroare.

După cum deja cunoașteți, toate clasele sunt impicit subclase ale clasei Object. Clasa Object are metoda toString() care returnează un obiect de tip String ce conțin numele clasei și codul hash al acesteia. Aveți posibilitatea de a supradefini această metodă pentru a afișa mai multe informații despre clasa dată.

Exemplul 6. Supradefinirea metodei toString()
class Elev {
private String nume, prenume;
private int virsta;
public Elev(String nume, String prenume, int virsta) {
this.nume = nume;
this.prenume = prenume;
this.virsta = virsta;
}
@Override
public String toString() {
return "Elev nume=" + nume + ", prenume=" + prenume + ", virsta=" + virsta;
}}

public class sConstructor {
public static void main(String[] args) {
Elev e1 = new Elev("Creanga", "Ion",50);
System.out.println(e1);
}}

Ce se va întâmpla dacă în clasa Elev nu va fi supradefinită metoda toString()? Vom obține rezultatul, numele clasei urmat de codul hash al acesteia:

Exemplul 7. Fără supradefinirea metodei toString() exemplul de mai sus ar trebui să arate în felul următor:
class Elev {
private String nume, prenume;
private int virsta;
public Elev(String nume, String prenume, int virsta) {
this.nume = nume; this.prenume = prenume; this.virsta = virsta;
}
public String getNume() { return nume; }
public String getPrenume() { return prenume; }
public int getVirsta() { return virsta; }
}
public class sConstructor {
public static void main(String[] args) {
Elev e1 = new Elev("Creanga", "Ion",50);
System.out.println("Elev nume="+e1.getNume() + ", prenume="+ e1.getPrenume()+",
virsta="+e1.getVirsta());
}}

Avantajele polimorfismului în contextul lecției curente:
- Permite scrierea de cod generic care poate fi utilizat cu diferite tipuri de date, astfel înbunătățind reutilizarea codului.
- Facilitează modificarea și extinderea codului existent făcându-l în acest sens flexibil.
- Permite scrierea de cod mai concis și mai ușor de citit.
- Permite optimizarea codului pentru anumite tipuri de date ceea ce duce la o performanță mai rapidă.

Dezavantajele polimorfismului:
- Pot apărea erori dacă tipul real al obiectului nu este compatibil cu metoda apelată.
- Codul este mai dificil de înțeles și de depanat.
- Erorile de compilare pot fi mai dificil de identificat și de remediat în codul polimorfic.

Urmează un spot video educațional la tema de astăzi:

 


Să aveți o zi deosebită!
❤️