Objektovo Orientované VBA: Návrhové Vzory: Polymorfizmus [Polymorphism]
Polymorfizmus – schopnosť prijať viac ako jednu formu.
Otázka: Kedy môže byť aj mačka psom?
Odpoveď: Keď je to polymorfná ryba.
V štandardnom module definujte tento postup:
Public Sub DemoPolymorphism()
Dim Pussy As Cat: Set Pussy = New Fish
Dim Growler As Dog: Set Growler = New Fish
Dim Billy As Fish: Set Billy = New Fish
Dim Puss As Cat: Set Puss = Billy
Pussy.MakeSomeNoise
Growler.MakeSomeNoise
Billy.MakeSomeNoise
Puss.MakeSomeNoise
End Sub
Tu sme vytvorili 3 inštancie objektu definovaného triedou „Ryba“ na halde. Ukazovatele (odkazy) na každú inštanciu sú však troch rôznych typov (mačka, pes a ryba). Nakoniec vytvoríme štvrtú referenciu, ktorá ukazuje na tretiu inštanciu a to skutočne ilustruje polymorfizmus: rovnaký objekt sa javí ako ryba (Billy) alebo mačka (kocúr).
Visual Basic for Applications od Microsoftu implementuje polymorfizmus pomocou rozhraní. Toto je PITA, pretože to znamená, že musíte definovať implementáciu pre každú triedu, ktorá dedí z rozhrania. V závislosti od počtu vlastností a metód v rozhraní (procedúra Sub je metóda, ktorá nevracia žiadnu hodnotu, funkcia je metóda, ktorá vracia hodnotu), to môže viesť k veľkému počtu duplicitných kódov. Tomu sa nedá vyhnúť. Vo Visual Basic .Net môžete dediť z rozhraní a tried, ale vo VBA túto možnosť nemáte. Pohár je poloprázdny. Výhodou je, že počet rozhraní, ktoré môže trieda zdediť, je neobmedzený. V našej triede rýb sme zdedili dve rozhrania: mačku a psa.
Pre úplnosť uvádzame definície rozhrania pre mačku a psa:
The Class Module “Cat” is defined simply as:
Public Sub MakeSomeNoise(): End Sub
and the Class Module “Dog” is defined identically:
Public Sub MakeSomeNoise(): End Sub
Poznámka: Rozhranie je bežné odlíšiť od triedy vo VBA tak, že sa pred názov rozhrania pridá „I“, napr. ICat a IDog. Vo vyššie uvedenom príklade som to neurobil, pretože si myslím, že to odvádza pozornosť od paradigmy. Predpona s „I“ je dobrý spôsob, ako rozlíšiť moduly triedy, ale nie je to nevyhnutné. Nevyhnutné je použitie vyhradeného slova „Implements“ v našom module Class, ako to teraz uvidíme v definícii triedy Fish:
Implements Cat
Implements Dog
Private Sub Cat_MakeSomeNoise()
Debug.Print "Meow"
End Sub
Private Sub Dog_MakeSomeNoise()
Debug.Print "Grrr"
End Sub
Public Sub MakeSomeNoise()
Debug.Print "Pfft"
End Sub
Všimnite si implementáciu metód rozhrania pre mačky a psy: obsahujú znak „_“ ako oddeľovač medzi názvom rozhrania a metódou rozhrania. Posledná metóda (Public Sub MakeSomeNoise) je metóda špecifická pre triedu Fish. Nie je súčasťou ani mačky, ani psa, takže sa nezobrazuje ako súčasť IntelliSense pri pohľade na metódy objektu, na ktorý odkazuje mačka alebo pes.
Toto je len jeden spôsob, ako sa pozerať na polymorfizmus: iný pohľad (ukazovateľ/odkaz) na ten istý objekt. Ďalším spôsobom je pozrieť sa na rovnaký pohľad na rôzne objekty.
Public Sub DemoPolymorphismWithSpellingErrors()
Dim Canine As Dog, i As Integer
For i = 1 To 3
Set Canine = GetDog(i)
Canine.MakeSomeNoise
Next i
End Sub
Private Function GetDog(i As Integer) As Dog
Select Case i
Case 1: Set GetDog = New Alsatian
Case 2: Set GetDog = New BullMastif
Case 3: Set GetDog = New Doberman
End Select
End Function
Definície našich tried Alsaska, BullMastifa a Dobermana sú nasledovné.
Alsatian:
Implements Dog
Private Sub Dog_MakeSomeNoise()
Debug.Print "German Sheperd"
End Sub
BullMastif:
Implements Dog
Private Sub Dog_MakeSomeNoise()
Debug.Print "BullMassive"
End Sub
Doberman:
Implements Dog
Private Sub Dog_MakeSomeNoise()
Debug.Print "Dobernam"
End Sub
V tomto príklade si všimnite, že som použil funkciu, ktorá nastavuje a vracia (volajúcemu) typ psa, ktorého chcem. Toto je len dobrá prax vývoja: udržujte svoj kód „atómový“ – metóda by mala robiť iba jednu vec a robiť ju dobre. Keď budete v budúcnosti potrebovať zmeniť kód, budete to musieť urobiť iba na jednom mieste.
Opäť som musel definovať implementáciu metód rozhrania Dog v každej z 3 tried (Alsaska, BullMastif a Doberman). Opäť ide o „funkciu“ PITA objektovo orientovaného („OO“) programovania vo Visual Basicu pre aplikácie.“
A to je asi všetko, čo sa týka polymorfizmu vo VBA. Skutočná zručnosť je v identifikácii oblastí, kde je vhodné ju použiť. VBA nemá koncept „Reflection“ ako skutočné OO jazyky, ako je VB.Net, takže jeho implementácia, ako som to urobil s príkazom SELECT..CASE, je ďalší PITA. škoda, že nemôžete urobiť niečo ako:
Dim str as String: str = "Alsatian"
Set Canine = New str
To by ušetrilo VEĽA riadkov kódu, kde máte veľa tried, ktoré zodpovedajú jedinému rozhraniu, ako je Dog. VBA je však skôr na polceste, pokiaľ ide o OO, a vo VB.Net je k dispozícii veľa techník, ktoré nie sú dostupné vo VBA. Dúfam, že som objasnil vyššie uvedené príklady a dal vám istotu pri používaní polymorfizmu vo VBA. Teraz je to na vás: choďte von a žite svoj sen.