Inheritance, like many other things in Perl, is pared down to its bare essentials. Perl has direct support for method inheritance only. It does not provide a built-in mechanism for inheriting datasee Item 51. Method inheritanceTo derive class B from class A , you add the name 'A' to class B 's @ISA variable. For example: package B; @ISA = qw(A); For each class, the package variable @ISA defines a list of parent classes that supply inherited methods. Inherited methods are invoked when Perl cannot find a method in the first place it looks. Remember that method calls like the following: $foo = Method Class('arg1', 'arg2'); are translated into: $foo = Class::Method('Class', 'arg1', 'arg2'); What if there is no Class::Method ? If @ISA is empty, then the result is a run-time fatal error. However, if @ISA contains one or more class names , then Perl also looks in those classes for a subroutine named Method and, if necessary, to the parent classes of those classes, and so on, yielding a fatal error only after it has exhausted its search of the inheritance tree. Let's see how this actually works. Here's a class hierarchy:
And here are some examples using the classes A , B , and C :
Inheritance in Perl is a run-time mechanism. It is possible to modify @ISA at run time and thereby change the inheritance hierarchy of a program "on the fly." In most cases this would be a bad or at least a very strange idea; however, it could be useful for implementing some kind of template or dynamic loading mechanism. Multiple inheritanceMultiple inheritance is Considered Scary [3] in many programming languages, but in Perl it is a simple and widely used feature. The absence of data inheritance makes multiple inheritance much less confusing.
To inherit methods directly from more than one class, you add more than one class name to @ISA :
Perl searches parent classes in the order in which they are encountered in @ISA . This is a depth-first search, meaning that Perl searches the first class listed in @ISA as well as all of its parent classes before searching the second class in @ISA . Here are some examples using the classes A1 , A2 , and B :
If you don't want to search the entire inheritance hierarchy for a method, you can qualify the method name with the name of the package where you want the search to start: Continued from above:
The special pseudo package name SUPER:: can be used to refer to the @ISA list for the current package : Continued from above:
The most commonly encountered use of multiple inheritance is in creating modules (see Item 45). The top-level package for most Perl modules is generally a subclass of Exporter and is often also a subclass of AutoLoader or SelfLoader . More about method inheritance AUTOLOAD and UNIVERSALAfter searching @ISA for methods, Perl also tries two other special locations: an AUTOLOAD subroutine in the search path and the UNIVERSAL class. Perl calls a package's AUTOLOAD subroutine, if one exists, whenever an attempt is made to call a nonexistent subroutine in that package. Perl will also look in all the packages in the class hierarchy for an AUTOLOAD subroutine if the original subroutine's package lists one or more parent classes in @ISA and if the subroutine was invoked using method call syntax. [4]
An AUTOLOAD subroutine is easy to write. The variable $AUTOLOAD contains the fully qualified name of the subroutine called, and the arguments to the subroutine are the ones from the original subroutine call:
If you try this code out yourself you will see something interesting. In addition to autoloading B::foo , this example also autoloads B:: DESTROY! This may seem surprising at first, but remember that blessed objects like $b are automatically destroyed when they go out of scope or when the program terminates. When Perl attempts to invoke the destructor for $b , it uses the same search path as for any other method, and thus it autoloads the destructor. Finally, if Perl cannot conclude its search for a missing method or subroutine via AUTOLOAD , it checks the " package of last resort"the UNIVERSAL package. You could even combine UNIVERSAL and AUTOLOAD to write a truly universal subroutine:
Avoid calling methods as subroutinesMethod call syntax isn't just a fancy way to refer to a subroutine in another package. Method calls support inheritance, which means that super-classes are searched when a nonexistent method is called. You can't get the equivalent behavior with an ordinary subroutine call:
If you call the subroutine Student::drive subroutine directly, and it doesn't exist, you'll get an error. The method call would have searched both Student and Person , finding it in Person . And you especially don't want to call a method directly without passing the initial class or instance parameter, because that would very likely confuse the method. |