Polimorfizmus (informatika)

A számítástechnika és típusa elmélet , polimorfizmus , a régi görög Polus (sok) és morphe (forma), a fogalom, hogy egyetlen felületen entitások, amelyek különböző típusú . Például, olyan műveletek, mint szorzás így kiterjeszthető skaláris a vektorok vagy mátrixok , kívül, skaláris a funkciók vagy húrok , stb Számos alapvetően különböző típusú polimorfizmus létezik:

A polimorfizmus fajtái
Fajta Név az objektum-orientált programozásban Név a funkcionális programozásban Leírás
ad hoc polimorfizmus túlterhelés Egy egyetlen interfész van végrehajtott számos rutinok , amelyek azonos azonosítóval , potenciálisan heterogén, azaz mindegyik rutin, amelynek különböző kombinációja típusú annak paramétereit , hogy ez egy osztályának tagja, vagy sem (a globális rutin).
paraméterezett polimorfizmus általános programozás polimorfizmus Egy egyetlen interfész van végre egyetlen rutin segítségével általános típus legalább egyik paraméter , hogy a rutin egy osztályának tagja, vagy sem (a globális rutin).
polimorfizmus altípussal ( öröklés ) öröklés útján kialakuló polimorfizmus inklúziós polimorfizmus Egy egyedi felületet egy tag rutin valósít meg, amelynek azonos azonosítója van az azonos öröklési hierarchiába tartozó osztályokban.

Az alkalmazott számítógépes nyelvtől függően a polimorfizmus különböző, a nyelvben rejlő eszközökkel vagy tervezési minták alkalmazásával érhető el .

Ad hoc polimorfizmus

Az ad hoc polimorfizmus vagy a függvények túlterhelése abból áll, hogy több függvényt vagy módszert deklarálunk ugyanazzal a névvel, de különböző paraméterekkel (számuk vagy típusuk szerint). Attól függően, hogy a nyelv statikusan vagy dinamikusan van-e gépelve, az adott paraméterek helyes megvalósításának meghatározása fordítási vagy futási időben történik. Itt van egy példa a C ++ túlterhelésére  :

#include <string> #include <iostream> void fonctionSurchargee(std::string str) { std::cout << "Implémentation 1 (string)" << std::endl; } void fonctionSurchargee(int x) { std::cout << "Implémentation 2 (int)" << std::endl; } int main(int argc, char *argv[]) { fonctionSurchargee("Hello World!"); // Affiche : Implémentation 1 (string) fonctionSurchargee(42); // Affiche : Implémentation 2 (int) return 0; }

Paraméteres polimorfizmus

A paraméterezett polimorfizmus a paraméterezett típusokra alkalmazható függvények meghatározásából áll . Például lehetőség van arra, hogy meghatározza az azonos concat funkció , amely lehetővé teszi a két listákat kell összefűzött típusától függetlenül az adatok tartalmaznak. Ebben az esetben a concat függvény típusát jegyezzük fel:

ahol α egy olyan paraméter, amely a listák adattípusát reprezentálja. Az α megfelelhet egész szám, valós, karakterlánc, β lista stb.

A paraméterezett polimorfizmust a Caml , a Haskell , a PureScript és a Scala nyelv használja . Például a Haskellben a függvény egy lista első n elemét takeadja vissza . A tolmács által visszaadott függvény specifikációja:

take :: Int -> [a] -> [a]

Az a típus egy olyan típusú változó, amely bármilyen típusnak megfelel, tehát a paraméterezett polimorfizmust támogató függvény.

Több objektum-orientált nyelvek végre paraméteres polimorfizmus, mint például a Java generikus típusok és C ++ a sablonokat . Utóbbiban kifejezhetnénk a concat függvényt :

#include <list> template<class a> std::list<a> concat(std::list<a> list1, std::list<a> list2) { return list1.insert(list1.end(),list2.begin(),list2.end()) }

Polimorfizmus altípussal (öröklés)

Típusok létrehozása

Az ötlet az, hogy egy típusból induljon ki és módosítsa. Például mi is létrehozhatunk egy bázis osztály , majd végezze el a származtatott osztályokban.

Ez a koncepció az objektumorientált megközelítéshez kapcsolódik .

A C ++ #include <numbers> class Forme { public: // Méthode virtuelle pure virtual float Aire() = 0; // Une classe de base d’une hiérarchie polymorphe // doit toujours (ou presque) avoir un destructeur virtuel virtual ~Forme() {} }; class Carre : public Forme { public: float Aire() override { return m_cote * m_cote; } private: float m_cote; }; class Cercle : public Forme { public: float Aire() override { return std::numbers::pi<float> * m_rayon * m_rayon; } private: float m_rayon; }; A java public abstract class Forme { public abstract float aire() ; } public class Carre extends Forme { private float cote; @override public float aire() { return cote * cote; } } public class Cercle extends Forme { private float rayon; @override public float aire() { return (float) Math.PI*rayon*rayon; } } A Python import math class Forme: def aire(self): raise NotImplementedError() class Carre(Forme): def __init__(self, cote): self.cote = cote def aire(self): return self.cote * self.cote class Cercle(Forme): def __init__(self, rayon): self.rayon = rayon def aire(self): return math.pi * self.rayon * self.rayon A C # public abstract class Forme { public abstract float Aire(); } public class Carre : Forme { private float cote; public override float Aire() { return (float) Math.Pow(cote, 2); } } public class Cercle : Forme { private float rayon; public override float Aire() { return (float) ( Math.PI * Math.Pow(rayon, 2) ); } } A Eiffel deferred class FORME feature aire: REAL deferred end end class CARRE inherit FORME feature cote: REAL aire: REAL do Result := cote^2 end end class CERCLE inherit FORME MATH feature rayon: REAL aire: REAL do Result := Pi * rayon^2 end end

Altípusok használata

A virtuális függvényeknek köszönhetően csak az alaposztály felhasználásával készíthetünk algoritmust, amely automatikusan meghívja a származtatott osztályok függvényeit. Egészen egyszerűen elmondhatjuk, hogy egy polimorf lista különböző objektumokat tartalmaz, és ezeknek az objektumoknak a típusától függően, amikor egy módszert alkalmaznak, a lista egyik objektumára alkalmazzák, annak funkciójának megfelelően.

A C ++ template<typename Size> float AireTotal(std::array<Forme*, Size> arr) { float f = 0; for (auto forme : arr) f+= forme->Aire(); // le programme détermine automatiquement quelle fonction appeler return f; } // ... std::array<Forme*, 3> tableau { new Carre, new Cercle, new Carre }; AireTotal(tableau); // ... A java float aireTotal(Forme[] tabl) { float s=0; for(Forme forme : tabl) { s += forme.aire(); // le programme détermine automatiquement quelle fonction appeler } return s; } // ... Forme[] tableau = { new Carre(), new Cercle(), new Carre() }; aireT = aireTotal(tableau); //aireT aura été défini comme float // ... A C # //... private float _aireT; readonly Forme[] _tableau = { new Carre(), new Cercle(), new Carre() }; //... float AireTotal(Forme[] tabl) { float s = 0; foreach (Forme form in tabl) { s += form.Aire(); // le programme détermine automatiquement quelle fonction appeler } return s; } //... _aireT = AireTotal(_tableau); //... A Eiffel aireTotal (tab: ARRAY [FORME]): REAL do -- Result = 0.0 par défaut from tab.start until tab.after loop Result := Result + tab.item.aire tab.forth end end

A polimorfizmus érdeke

Azzal, hogy ugyanazt a módszernevet javasoljuk több különböző típusú objektumra, a polimorfizmus sokkal általánosabb programozást tesz lehetővé. A fejlesztőnek nem kell tudnia a módszer programozásakor az objektum pontos típusát, amelyre a módszert alkalmazzák. Csak tudnia kell, hogy ez az objektum fogja megvalósítani a módszert.

Így a bankszámlákra vonatkozó kamatszámító szoftver a klasszikus programozásban (álkód) így nézne ki:

case MonCompteBancaire PEA : MonCompteBancaire.calculeInteretPEA PEL : MonCompteBancaire.calculeInteretPEL LivretA : MonCompteBancaire.calculeInteretLivretA end case

Ha új típusú PERP bankszámla jelenik meg (és ezzel együtt egy új számítás), akkor egyrészt meg kell írni az új calculatesInteretPERP módszert, másrészt módosítani kell a fenti számítás összes hívását. A legjobb esetben elkülönítik és megosztják, így csak egy módosításra lesz szükség. A legrosszabb esetben több száz módosítási felhívás lehet.

A polimorfizmus esetén az összes metódusnak ugyanaz a neve lesz a "calcInterest", de különböző kódokkal rendelkezik (számlatípusonként egy).
A felhívás a következő formájú lesz:

MonCompteBancaire.calculeInteret

Amikor az új fiók megérkezik, nem lesz szükség a kód módosítására. A valódi felhasználási módot futás közben automatikusan a nyelv választja meg, míg az előző esetben a fejlesztőnek kellett programoznia ezt a választást. De a programozónak létre kell hoznia egy további objektum osztályt a megfelelő kód megvalósításához, amelyet a virtuális módszerek táblázatának hozzárendelése hív meg, amely valóban végrehajt egy dobozt ennek az összetevőnek megfelelően.

<img src="https://fr.wikipedia.org/wiki/Special:CentralAutoLogin/start?type=1x1" alt="" title="" width="1" height="1" style="border: none; position: absolute;">