{ package Animal;
sub speak {
my $class = shift;
print "a $class goes ", $class->sound, "!\n";
}
}
{ package Mouse;
@ISA = qw(Animal);
sub sound { "squeak" }
sub speak {
my $class = shift;
print "a $class goes ", $class->sound, "!\n";
print "[but you can barely hear it!]\n";
}
}
Mouse->speak;
which results in:
a Mouse goes squeak!
[but you can barely hear it!]
Here, Mouse has its own speaking routine, so
Mouse->speak doesn't
immediately invoke Animal->speak. This is known
as overriding. You use overriding to shadow
the method in the derived class (Mouse) because
you have a specialized version of the routine, instead of calling the
more general base class's method (in
Animal). In fact, you didn't even
need to initialize @Mouse::ISA to say that a
Mouse was an Animal at all
because all the methods needed for speak are
defined completely with Mouse.
How can you avoid that? Can you say somehow that a
Mouse does everything any other
Animal does, but add in the extra comment? Sure!
As your first attempt, you can invoke the
Animal::speak method directly:
{ package Animal;
sub speak {
my $class = shift;
print "a $class goes ", $class->sound, "!\n";
}
}
{ package Mouse;
@ISA = qw(Animal);
sub sound { "squeak" }
sub speak {
my $class = shift;
Animal::speak($class);
print "[but you can barely hear it!]\n";
}
}
Note that because you've stopped using the method
arrow, you have to include the $class parameter
(almost surely the value of "Mouse") as the first
parameter to Animal::speak,.
Why did you stop using the arrow? Well, if you invoke
Animal->speak there, the first parameter to the
method is "Animal," not
"Mouse", and when the time comes for it to call
for the sound, it won't have the
right class to select the proper methods for this object.
Invoking Animal::speak directly is a mess,
however. What if Animal::speak
didn't exist before and was inherited from a class
mentioned in @Animal::ISA? For example, suppose
the code was:
{ package LivingCreature;
sub speak { ... }
...
}
{ package Animal;
@ISA = qw(LivingCreature);
# no definition for speak( )
...
}
{ package Mouse;
@ISA = qw(Animal);
sub speak {
...
Animal::speak( ... );
}
...
}
Because you no longer use the method arrow, you get one and only one
chance to hit the right subroutine. You'll look for
it in Animal, and not find it, and the program
aborts.