Sometimes the syntax of inheritance is built into the core of the language, and sometimes it's not. Perl has no special syntax for specifying the class (or classes) to inherit from. Instead, it's all strictly in the semantics. Each package can have a variable called
@ISA, which governs (method) inheritance. If you try to call a method on an object or class, and that method is not found in that object's package, Perl then looks to @ISA
for other packages to go looking through in search of the missing method.
Like the special per-package variables recognized by Exporter (such as
@EXPORT,
@EXPORT_OK,
@EXPORT_FAIL,
%EXPORT_TAGS, and
$VERSION), the @ISA
array
must be a package-scoped global and not a file-scoped lexical created via my.
Most classes have just one item in their @ISA
array. In this case, we have what's called ``single inheritance'', or
SI for short.
Consider this class:
package Employee; use Person; @ISA = ("Person"); 1;
Not a lot to it, eh? All it's doing so far is loading in another class and stating that this one will inherit methods from that other class if need be. We have given it none of its own methods. We rely upon an Employee to behave just like a Person.
Setting up an empty class like this is called the ``empty subclass test''; that is, making a derived class that does nothing but inherit from a base class. If the original base class has been designed properly, then the new derived class can be used as a drop-in replacement for the old one. This means you should be able to write a program like this:
use Employee my $empl = Employee->new(); $empl->name("Jason"); $empl->age(23); printf "%s is age %d.\n", $empl->name, $empl->age;
By proper design, we mean always using the two-argument form of
bless,
avoiding direct access of global data, and not
exporting anything. If you look back at the Person::new() function we
defined above, we were careful to do that. There's a bit of package data
used in the constructor, but the reference to this is stored on the object
itself and all other methods access package data via that reference, so we
should be ok.
What do we mean by the Person::new() function -- isn't that actually a method? Well, in principle, yes.
A method is just a function that expects as its first argument a class name (package) or object (blessed reference). Person::new() is the function that both the
Person->new
method and the Employee->new
method end up calling. Understand that while a method call looks a lot like
a function call, they aren't really quite the same, and if you treat them
as the same, you'll very soon be left with nothing but broken programs.
First, the actual underlying calling conventions are different: method
calls get an extra argument. Second, function calls don't do inheritance,
but methods do.
Method Call Resulting Function Call ----------- ------------------------ Person->new() Person::new("Person") Employee->new() Person::new("Employee")
So don't use function calls when you mean to call a method.
If an employee is just a Person, that's not all too very interesting. So let's add some other methods. We'll give our employee data fields to access their salary, their employee ID, and their start date.
If you're getting a little tired of creating all these nearly identical methods just to get at the object's data, do not despair. Later, we'll describe several different convenience mechanisms for shortening this up. Meanwhile, here's the straight-forward way:
sub salary { my $self = shift; if (@_) { $self->{SALARY} = shift } return $self->{SALARY}; }
sub id_number { my $self = shift; if (@_) { $self->{ID} = shift } return $self->{ID}; }
sub start_date { my $self = shift; if (@_) { $self->{START_DATE} = shift } return $self->{START_DATE}; }