Saturday, February 29, 2020 09:35

Polimorfism

Al treilea principiu fundamental al Programării Orientate pe Obiecte (OOP) se numește polimorfism. La un nivel fundamental, polimorfia se referă la capacitatea de a avea mai multe forme sau de a se transforma în mai multe forme. Provine din termenii greci poly, care înseamnă „multiplu” și morf, care înseamnă „formă”.

Deși are o definiție descurajantă, polimorfismul este destul de simplu de înțeles. Să luăm în considerare o clasă de bază:

Deci, nimic complicat. Doar o clasă numită Animal, cu două metode, Mananca() și Doarme(), care sunt comune tuturor animalelor.

Să creăm două clase care reprezintă animale concrete:

Până acum, totul bine, atât Pisica, cât și Caine sunt clase care moștenesc din Animal, ceea ce înseamnă că sunt și ele de tip Animal, pe lângă propriul tip, ceea ce înseamnă că ambele posedă acum metodele clasei Animal, Doarme() și Mananca().

Imaginați-vă acum că ați dori să aveți un număr aleatoriu de instanțe, atât de pisici, cât și de câini, și că va trebui să le țineți evidența. Primul impuls ar fi crearea a două array-uri, unul de tip Pisica, unul de tip Caine, și manipularea separată a acestora:

Aceasta ar putea fi o abordare, dar nu ar fi în totalitate corectă; sau, mai degrabă, nu ar fi cea mai eficientă. Dacă ați avea sute de tipuri de animale? Evidența lor ar deveni rapid destul de greoaie.

Pe de altă parte, să revizuim ce este polimorfismul, la nivel de bază: „capacitatea de a lua (sau a avea) mai multe forme”. Ei bine, superb, nu-i așa? Nu este exact ceea ce am avea nevoie în această situație? Așadar, primul pas către începerea utilizării comportamentului polimorf în codurile noastre este să căutăm un comportament comun tuturor obiectelor noastre (sunt toate animale, toate dorm, mănâncă), chiar dacă implementarea specifică a comportamentului comun diferă de la obiect la obiect. Cu alte cuvinte, chiar dacă o pisică nu este un câine, iar un câine nu este o pisică, ambele sunt animale. Ele au același comportament de a dormi și de a mânca, chiar dacă acest comportament este implementat în mod diferit pentru ele. Polimorfismului nu-i pasă că pisicile mănâncă șoareci și că vacile mănâncă iarbă, îi pasă doar că atât pisicile cât și vacile au capacitatea de a mânca, ceea ce este o acțiune polimorfă (poate avea mai multe forme). În această nouă lumină, Animal este un obiect polimorf. Nu ne pasă dacă este o pisică sau o balenă, ne pasă doar că ambele sunt animale.

Cum ne ajută asta? Priviți aici:

Dacă vă amintiți din capitolul Array-uri, nu putem instanția un array cu un tip diferit de tipul cu care l-am declarat. Deci, cum am putut să adaug o Pisica pe prima poziție a array-ului de tip Animal și apoi să adaug un Caine pe a doua poziție?! Dacă l-am declarat de tip Animal, ar trebui să mi se permită să adaug doar instanțe de tip Animal în elementele sale! Și apoi, am putut să apelez metoda Mananca() pe toate animalele din array, fără să-mi pese de tipul lor actual!

Et voila, magia polimorfismului! Deoarece atât Caine cât și Pisica moștenesc din Animal, ele SUNT și animale, pe lângă faptul că sunt pisici și câini. Acest comportament de moștenire este cunoscut și ca o relație „este o/un”. O pisică „este un” animal. Veți găsi, de asemenea, o altă definiție a polimorfismului, care descrie, practic, același concept, în cuvinte diferite: polimorfismul permite tratarea obiectelor unei clase derivate ca obiecte ale clasei sale de bază.

Ar trebui să știți acum ce este polimorfismul, concret. Dar, fiți atenți, poate fi înșelător. Luați în considerare acest exemplu:

Exemplul de mai sus va face programul să își oprească execuția cu o eroare. De ce? În primul rând, deoarece polimorfismul nu este bidirecțional. Orice pisică ESTE un animal, dar NU orice animal este o pisică. Deci, putem efectua doar un comportament polimorf pe concepte generice, comune, nu pe implementări concrete. În cuvinte simple, Animal poate lua multe forme, Pisica este doar Pisica, o singură formă de animal.

Deoarece în exemplul de mai sus am adăugat și un Caine pe a doua poziție a array-ului, programul a generat o eroare atunci când am folosit bucla foreach sub forma de Pisica. Un câine nu este cu siguranță o pisică, iar programul nu va putea converti un obiect de tip câine într-o pisică.

Modalitatea de evitare a acestui lucru este folosirea unui cuvânt cheie special din C#, operatorul is:

Polimorfismul în C# este clasificat în două tipuri principale:

  • polimorfism la timpul compilării, cunoscut și sub denumirea de polimorfism static, care se referă practic la capacitatea de a apela o metodă cu mai multe tipuri de parametri (supraîncărcarea metodelor) și, de asemenea, la supraîncărcarea operatorilor.
  • polimorfism la timpul execuției, cunoscut și sub denumirea de polimorfism dinamic, sau legare tardivă, care poate fi obținut fie sub forma explicată mai sus (capacitatea de a utiliza proprietăți similare ale diferitelor obiecte), fie prin suprascrierea metodelor, ceea ce înseamnă implementarea de funcționalități personalizate pentru comportamente comune (toate animalele mănâncă, acțiune ce este definită în clasa de bază, dar care poate fi suprascrisă în clasele copil, concrete, cu un comportament alimentar personalizat pentru fiecare tip de animal).

Polimorfismul poate avea o asemănare izbitoare cu abstracția, dar este în cea mai mare parte legat de suprascrierea metodelor în clasele derivate, pentru a le schimba comportamentul inițial, moștenit din clasa de bază. Abstracția este asociată cu crearea unei interfețe a unei componente sau funcționalități (definirea unui rol). Dar, voi explica acest lucru mai în detaliu atunci când voi scrie despre interfețe.

Comments

comments

Tags: , , , , ,

Leave a Reply



Do NOT follow this link or you will be banned from the site!