Overerving in Perl wordt geïmplementeerd met behulp van de array @ISA, die aangeeft van welke pakketten (klassen) het huidige pakket erft. Dit is niet de traditionele OO, zoals in veel andere talen, maar eerder een dynamische vervanging van ouders tijdens het zoeken naar methoden.
In vroege versies van Perl was er geen standaard objectgeoriënteerde aanpak. Voor ondersteuning van overerving werd de array @ISA (ISA = Is A) geïntroduceerd, waarin de ouderklassen worden opgesomd. Perl zoekt naar methoden eerst in de klasse van het object zelf, daarna in volgorde bij de ouders, wat bepaalde flexibiliteit biedt, maar ook zijn eigen bijzonderheden met zich meebrengt.
De manieren van overerving via @ISA kunnen gemakkelijk de encapsulatie breken. Daarnaast vereist meervoudige (multilevel) overerving een zorgvuldige behandeling van de volgorde van ouders om onverwachte methodenconflicten te voorkomen. Een belangrijk punt is de volgorde van het zoeken naar methoden (Method Resolution Order), die niet altijd duidelijk is, vooral bij het gebruik van CPAN-modules (bijvoorbeeld klassen uit Moose, base of parent).
Voor eenvoudige overerving in Perl wordt de array @ISA gedeclareerd:
package Parent; sub hello { print "Hello from parent! "; } package Child; our @ISA = ('Parent'); Child::hello(); # Geeft weer: Hello from parent!
In echte projecten wordt vaak gebruikgemaakt van de pragma base of parent om het werken met overerving te vereenvoudigen en de veiligheid te vergroten.
@ISA.Kan de BASE-pragma of het gebruik van de array @ISA methoden van de ouder aan de kindklasse toevoegen na de uitvoering van het programma?
Nee, Perl staat overerving alleen toe tijdens de compilatie van het script, niet tijdens de uitvoering. Als wijzigingen in @ISA tijdens de uitvoering plaatsvinden, is het reëel dat ze niet van invloed zijn op alle al gedeclareerde objecten, wat vreemde problemen kan veroorzaken.
package Parent; sub hello { print "parent "; } package Child; our @ISA = ('Parent'); # Het is niet aan te raden om @ISA te wijzigen na het maken van objecten
Wat gebeurt er als dezelfde methode in meerdere ouderklassen in @ISA wordt gedeclareerd?
De eerste gevonden in de volgorde die in @ISA is opgegeven, wordt aangeroepen. Dit kan leiden tot onverwacht gedrag, vooral bij meervoudige overerving.
package Base1; sub hello { print "Base1 "; } package Base2; sub hello { print "Base2 "; } package Derived; our @ISA = ('Base1', 'Base2'); Derived::hello(); # Geeft weer: Base1
Kan ik dynamisch een klasse aan @ISA toevoegen en toegang krijgen tot zijn methoden?
Ja, dat kan, maar dit wordt ten zeerste afgeraden, omdat het de structuur van het programma kan breken, kan leiden tot fouten in de methode-resolutie en runtime-fouten kan veroorzaken.
@ISA tijdens de uitvoering van het programmaparent/base, wat de onderhoudbaarheid vermindertIn een project wijzigen ze handmatig de array @ISA in een lus om functionaliteit toe te voegen aan protocolklassen, om methoden van dynamisch gekoppelde modules onder bepaalde voorwaarden over te nemen.
Voordelen:
Nadelen:
Voor het uitbreiden van een klasse gebruiken ze de pragma parent, waarbij ze de volgorde van ouders strikt controleren en duidelijk de methoden definiëren die kunnen worden overschreven.
Voordelen:
Nadelen: