Die Vererbung in Perl wird durch das Array @ISA realisiert, das angibt, von welchen Paketen (Klassen) das aktuelle Paket erbt. Dies ist kein traditionelles OO wie in vielen anderen Sprachen, sondern eher eine dynamische Zuordnung von Eltern während der Methodensuche.
In frühen Versionen von Perl gab es keinen Standard-Objektansatz. Um die Vererbung zu unterstützen, wurde das Array @ISA eingeführt (ISA = Is A), in dem die Elternklassen aufgeführt sind. Perl sucht Methoden zuerst in der Klasse des Objekts selbst und dann der Reihe nach in den Eltern, was eine gewisse Flexibilität bietet, aber eigene Besonderheiten mit sich bringt.
Die Vererbung durch @ISA kann die Kapselung leicht brechen. Darüber hinaus erfordert mehrfache (mehrstufige) Vererbung einen sorgfältigen Umgang mit der Reihenfolge der Eltern, um unerwartete Konflikte bei Methoden zu vermeiden. Ein wichtiger Punkt ist die Reihenfolge der Methodensuche (Method Resolution Order), die nicht immer offensichtlich ist, insbesondere bei der Verwendung von CPAN-Modulen (zum Beispiel Klassen aus Moose, base oder parent).
Für einfache Vererbung in Perl wird das Array @ISA deklariert:
package Parent; sub hello { print "Hello from parent! "; } package Child; our @ISA = ('Parent'); Child::hello(); # Gibt aus: Hello from parent!
In realen Projekten werden häufig die Pragmas base oder parent verwendet, um die Arbeit mit Vererbung zu vereinfachen und sicherer zu gestalten.
@ISA.Kann BASE-pragma oder die Verwendung des Arrays @ISA Methoden des Elternteils zum Kindklasse nach dem Start des Programms hinzufügen?
Nein, Perl erlaubt die Vererbung während der Kompilierung des Skripts, nicht zur Laufzeit. Wenn Änderungen bei @ISA zur Laufzeit erfolgen, wird dies tatsächlich nicht alle bereits deklarierten Objekte betreffen, was zu seltsamen Problemen führen kann.
package Parent; sub hello { print "parent "; } package Child; our @ISA = ('Parent'); # Nach der Erstellung von Objekten wird empfohlen, @ISA nicht zu ändern
Was passiert, wenn dieselbe Methode in mehreren Elternklassen in @ISA deklariert wird?
Es wird die erste gefunden, in der Reihenfolge, die in @ISA angegeben ist, aufgerufen. Dies kann zu unerwartetem Verhalten führen, insbesondere bei mehrfacher Vererbung.
package Base1; sub hello { print "Base1 "; } package Base2; sub hello { print "Base2 "; } package Derived; our @ISA = ('Base1', 'Base2'); Derived::hello(); # Gibt aus: Base1
Kann man dynamisch eine Klasse zu @ISA hinzufügen und auf ihre Methoden zugreifen?
Ja, das ist möglich, aber sehr unempfohlen, da es die Struktur des Programms bricht, zu Fehlern bei der Methodenauflösung und Laufzeitfehlern führen kann.
@ISA zur Laufzeit des Programmsparent/base, was die Wartbarkeit verringertIn einem Projekt wird das Array @ISA manuell in einer Schleife geändert, um Klassenmethoden von dynamisch geladenen Modulen bedingt zu vererben.
Vorteile:
Nachteile:
Zur Erweiterung einer Klasse wird das pragma parent verwendet, um die Reihenfolge der Eltern streng zu kontrollieren und die Methoden zu definieren, die überschrieben werden können.
Vorteile:
Nachteile: