Ce este polimorfismul în C ++?
În C ++, polimorfismul determină o funcție membru să se comporte diferit pe baza obiectului care o cheamă / invocă. Polimorfismul este un cuvânt grecesc care înseamnă să aibă multe forme. Apare atunci când aveți o ierarhie de clase legate prin moștenire.
De exemplu, să presupunem că avem funcția makeSound (). Când o pisică apelează această funcție, va produce sunetul miau. Când o vacă invocă aceeași funcție, va oferi sunetul moow.
Deși avem o funcție, ea se comportă diferit în circumstanțe diferite. Funcția are multe forme; prin urmare, am atins polimorfismul.
În acest tutorial C ++, veți învăța:
- Ce este polimorfismul?
- Tipuri de polimorfism
- Compilați polimorfismul în timp
- Funcția de supraîncărcare
- Supraîncărcarea operatorului
- Polimorfism de rulare
- Anularea funcției
- Funcția virtuală C ++
- Compilare-Timp Polimorfism vs. Polimorfism în timp de execuție
Tipuri de polimorfism
C ++ acceptă două tipuri de polimorfism:
- Polimorfism în timp de compilare și
- Polimorfismul în timpul rulării.
Compilați polimorfismul în timp
Invocați funcțiile supraîncărcate prin potrivirea numărului și tipului de argumente. Informațiile sunt prezente în timpul compilării. Aceasta înseamnă că compilatorul C ++ va selecta funcția potrivită la momentul compilării.
Polimorfismul în timp de compilare se realizează prin supraîncărcarea funcției și supraîncărcarea operatorului.
Funcția de supraîncărcare
Supraîncărcarea funcției apare atunci când avem multe funcții cu nume similare, dar argumente diferite. Argumentele pot diferi în ceea ce privește numărul sau tipul.
Exemplul 1:
#includeusing namespace std;void test(int i) {cout << " The int is " << i << endl;}void test(double f) {cout << " The float is " << f << endl;}void test(char const *ch) {cout << " The char* is " << ch << endl;}int main() {test(5);test(5.5);test("five");return 0;}
Ieșire:
Iată o captură de ecran a codului:
Explicatie cod:
- Includeți fișierul antet iostream în codul nostru. Vom putea folosi funcțiile sale.
- Includeți spațiul de nume std în codul nostru. Vom putea folosi clasele sale fără să o apelăm.
- Creați o funcție numită test care ia un parametru întreg i. {Marchează începutul testului funcțional.
- Instrucțiune care trebuie executată dacă testul funcțional de mai sus este invocat / apelat.
- Sfârșitul corpului testului funcțional de mai sus.
- Creați o funcție numită test care ia un parametru float f. {Marchează începutul testului funcțional.
- Instrucțiune care trebuie executată dacă testul funcțional de mai sus este invocat / apelat.
- Sfârșitul corpului testului funcțional de mai sus.
- Creați o funcție numită test care ia un parametru de caracter ch. {Marchează începutul testului funcțional.
- Instrucțiune care trebuie executată dacă testul funcțional de mai sus este invocat / apelat.
- Sfârșitul corpului testului funcțional de mai sus.
- Apelați funcția main (). {Marchează începutul corpului funcției.
- Apelați testul funcțional și treceți 5 la acesta ca valoare a argumentului. Aceasta invocă funcția de testare care acceptă un argument întreg, adică prima funcție de testare.
- Apelați testul funcțional și transmiteți 5.5 ca valoare a argumentului. Aceasta va invoca funcția de testare care acceptă un argument float, adică a doua funcție de testare.
- Apelați testul funcțional și treceți cinci ca valoare a argumentului. Aceasta va invoca funcția de testare care acceptă un argument de caracter, adică a treia funcție de testare.
- Programul trebuie să returneze o valoare dacă rulează cu succes.
- Sfârșitul corpului funcției main ().
Avem trei funcții cu același nume, dar diferite tipuri de argumente. Am realizat polimorfism.
Supraîncărcarea operatorului
În Operator Overloading, definim o nouă semnificație pentru un operator C ++. De asemenea, modifică modul în care funcționează operatorul. De exemplu, putem defini operatorul + pentru a concatena două șiruri. Știm că este operatorul de adăugare pentru adăugarea de valori numerice. După definiția noastră, atunci când este plasată între numere întregi, le va adăuga. Când este plasat între șiruri, le va concatena.
Exemplul 2:
#includeusing namespace std;class ComplexNum {private:int real, over;public:ComplexNum(int rl = 0, int ov = 0) {real = rl;over = ov;}ComplexNum operator + (ComplexNum const &obj) {ComplexNum result;result.real = real + obj.real;result.over = over + obj.over;return result;}void print() {cout << real << " + i" << over << endl;}};int main(){ComplexNum c1(10, 2), c2(3, 7);ComplexNum c3 = c1+c2;c3.print();}
Ieșire:
Iată o captură de ecran a codului:
Explicatie cod:
- Includeți fișierul antet iostream în programul nostru pentru a-i folosi funcțiile.
- Includeți spațiul de nume std în programul nostru pentru a utiliza clasele sale fără a-l apela.
- Creați o clasă numită ComplexNum. {Marchează începutul corpului clasei.
- Utilizați modificatorul de acces privat pentru a marca variabilele ca private, ceea ce înseamnă că acestea pot fi accesate doar din clasă.
- Definiți două variabile întregi, reale și peste.
- Utilizați modificatorul de acces public pentru a marca constructorul ca public, ceea ce înseamnă că va fi accesibil chiar și din afara clasei.
- Creați constructorul clasei și inițializați variabilele.
- Inițializați valoarea variabilei reale.
- Inițializați valoarea variabilei peste.
- Sfârșitul corpului constructorului.
- Trebuie să trecem peste semnificația operatorului +.
- Creați rezultatul tipului de date de tipul ComplexNum.
- Folosiți operatorul + cu numere complexe. Această linie va adăuga partea reală a unui număr la partea reală a unui alt număr.
- Folosiți operatorul + cu numere complexe. Această linie va adăuga partea imaginară a unui număr la partea imaginară a unui alt număr.
- Programul va returna valoarea rezultatului variabilei la executarea cu succes.
- Sfârșitul definiției noului sens al operatorului +, adică supraîncărcare.
- Apelați metoda print ().
- Imprimați noul număr complex după adăugare pe consolă.
- Functia de sfarsit a corpului print ().
- Sfârșitul corpului clasei ComplexNum.
- Apelați funcția main ().
- Transmiteți valorile părților reale și complexe care trebuie adăugate. Prima parte a lui c1 va fi adăugată la prima parte a lui c2, adică 10 + 3. A doua parte a lui c1 va fi adăugată la a doua parte a lui c, adică 2 + 7.
- Efectuați o operație folosind operatorul + supraîncărcat și stocând rezultatul în variabila c3.
- Imprimați valoarea variabilei c3 pe consolă.
- Sfârșitul corpului funcției main ().
Polimorfism de rulare
Acest lucru se întâmplă atunci când metoda unui obiect este invocată / apelată în timpul rulării, mai degrabă decât în timpul compilării. Polimorfismul în timpul rulării este realizat prin suprasolicitarea funcției. Funcția care trebuie apelată / invocată este stabilită în timpul rulării.
Anularea funcției
Înlocuirea funcției apare atunci când unei funcții a clasei de bază i se dă o nouă definiție într-o clasă derivată. În acel moment, putem spune că funcția de bază a fost anulată.
De exemplu:
#includeusing namespace std;class Mammal {public:void eat() {cout << "Mammals eat… ";}};class Cow: public Mammal {public:void eat() {cout << "Cows eat grass… ";}};int main(void) {Cow c = Cow();c.eat();return 0;}
Ieșire:
Iată o captură de ecran a codului:
Explicatie cod:
- Importați fișierul antet iostream în programul nostru pentru a-i folosi funcțiile.
- Includeți spațiul de nume std în programul nostru pentru a utiliza clasele sale fără a-l apela.
- Creați o clasă numită Mamifer. {Marchează începutul corpului clasei.
- Folosiți modificatorul de acces public pentru a seta funcția pe care urmează să o creăm ca fiind accesibilă publicului. Va fi accesibil din afara acestei clase.
- Creați o funcție publică numită eat. {Marchează începutul corpului funcției.
- Imprimați instrucțiunea adăugată la funcția cout atunci când este invocată funcția eat ().
- Sfârșitul corpului funcției eat ().
- Sfârșitul corpului clasei Mamifere.
- Creați o clasă numită Vaca care moștenește clasa Mamifere. Vaca este clasa derivată, în timp ce mamiferul este clasa de bază. {Marchează începutul acestei clase.
- Utilizați modificatorul de acces public pentru a marca funcția pe care urmează să o creăm ca fiind accesibilă publicului. Va fi accesibil din afara acestei clase.
- Înlocuiți funcția eat () care a fost definită în clasa de bază. {Marchează începutul corpului funcției.
- Declarația de imprimat pe consolă atunci când este invocată această funcție.
- Sfârșitul corpului funcției eat ().
- Sfârșitul corpului clasei Vaca.
- Apelați funcția main (). {Marchează începutul corpului acestei funcții.
- Creați o instanță a clasei Vaca și dați-i numele c.
- Apelați funcția eat () definită în clasa Cow.
- Programul trebuie să returneze o valoare după finalizarea cu succes.
- Sfârșitul funcției main ().
Funcția virtuală C ++
O funcție virtuală este un alt mod de implementare a polimorfismului în timp de execuție în C ++. Este o funcție specială definită într-o clasă de bază și redefinită în clasa derivată. Pentru a declara o funcție virtuală, ar trebui să utilizați cuvântul cheie virtual. Cuvântul cheie ar trebui să preceadă declarația funcției din clasa de bază.
Dacă este moștenită o clasă de funcții virtuale, clasa virtuală redefinește funcția virtuală pentru a se potrivi nevoilor sale. De exemplu:
#includeusing namespace std;class ClassA {public:virtual void show() {cout << "The show() function in base class invoked… " << endl;}};class ClassB :public ClassA {public:void show() {cout << "The show() function in derived class invoked… ";}};int main() {ClassA* a;ClassB b;a = &b;a->show();}
Ieșire:
Iată o captură de ecran a codului:
Explicatie cod:
- Includeți fișierul antet iostream în cod pentru a-i folosi funcțiile.
- Includeți spațiul de nume std în codul nostru pentru a utiliza clasele sale fără a-l apela.
- Creați o clasă numită ClassA.
- Utilizați modificatorul de acces public pentru a marca un membru al clasei ca fiind accesibil publicului.
- Creați o funcție virtuală numită show (). Va fi o funcție publică.
- Textul de imprimat atunci când este invocat show () este invocat. Endl este un cuvânt cheie C ++, care înseamnă linie finală. Mută cursorul mouse-ului pe linia următoare.
- Sfârșitul corpului funcției virtuale show ().
- Sfârșitul corpului clasei ClassA.
- Crearea unei clase noi numită ClassB care moștenește clasa ClassA. ClassA devine clasa de bază în timp ce ClassB devine clasa derivată.
- Utilizați modificatorul de acces public pentru a marca un membru al clasei ca fiind accesibil publicului.
- Redefiniți funcția virtuală show () derivată în clasa de bază.
- Textul de imprimat pe consolă atunci când este invocată funcția show () definită în clasa derivată.
- Sfârșitul corpului funcției show ().
- Sfârșitul corpului clasei derivate, Clasa B.
- Apelați funcția main (). Logica programului ar trebui adăugată în corpul său.
- Creați o variabilă pointer numită a. Arată spre clasa numită ClassA.
- Creați o instanță a clasei numite ClassB. Instanței i se dă numele b.
- Atribuiți valorile stocate în adresa b din variabila a.
- Invocați funcția show () definită în clasa derivată. Legarea târzie a fost implementată.
- Sfârșitul corpului funcției main ().
Compilare-Timp Polimorfism vs. Polimorfism în timp de execuție
Iată diferențele majore dintre cele două:
Polimorfism în timp de compilare | Polimorfism în timpul rulării |
Se mai numește legare timpurie sau polimorfism static | Se mai numește legare tardivă / dinamică sau polimorfism dinamic |
Metoda este apelată / invocată în timpul compilării | Metoda este apelată / invocată în timpul rulării |
Implementat prin supraîncărcarea funcției și supraîncărcarea operatorului | Implementat prin metoda de suprascriere și funcții virtuale |
Exemplu, supraîncărcarea metodei. Multe metode pot avea nume similare, dar număr sau tipuri diferite de argumente | Exemplu, suprascrierea metodei. Multe metode pot avea un nume similar și același prototip. |
Execuție mai rapidă, deoarece descoperirea metodelor se face în timpul compilării | Execuție mai lentă, deoarece descoperirea metodelor se face în timpul rulării. |
Este oferită mai puțină flexibilitate pentru rezolvarea problemelor, deoarece totul este cunoscut în timpul compilării. | Se oferă multă flexibilitate pentru rezolvarea problemelor complexe, deoarece metodele sunt descoperite în timpul rulării. |
Rezumat:
- Polimorfismul înseamnă a avea multe forme.
- Apare atunci când există o ierarhie de clase legate prin moștenire.
- Cu polimorfismul, o funcție se poate comporta diferit pe baza obiectului care o invocă / o numește.
- În polimorfismul în timp de compilare, funcția care trebuie invocată este stabilită în timpul timpului de compilare.
- În polimorfismul de rulare, funcția care trebuie invocată este stabilită în timpul rulării.
- Polimorfismul în timp de compilare este determinat prin supraîncărcarea funcției și supraîncărcarea operatorului.
- În supraîncărcarea funcției, există multe funcții cu nume similare, dar argumente diferite.
- Parametrii pot diferi ca număr sau tip.
- În supraîncărcarea operatorului, este definit un nou sens pentru operatorii C ++.
- Polimorfismul în timpul rulării este realizat prin suprasolicitarea funcției.
- În funcție de suprascriere, o clasă derivată oferă o nouă definiție unei funcții definite în clasa de bază.