To make a class a subclass of another class, use parent
pragma:
package Point;
use strict;
...
1;
package Point2D;
use strict;
use parent qw(Point);
...
1;
package Point3D;
use strict;
use parent qw(Point);
...
1;
Perl allows for multiple inheritance:
package Point2D;
use strict;
use parent qw(Point PlanarObject);
...
1;
Inheritance is all about resolution which method is to be called in a particular situation. Since pure Perl does not prescribe any rules about the data structure used to store object data, inheritance has nothing to do with that.
Consider the following class hierarchy:
package GeometryObject;
use strict;
sub transpose { ...}
1;
package Point;
use strict;
use parent qw(GeometryObject);
sub new { ... };
1;
package PlanarObject;
use strict;
use parent qw(GeometryObject);
sub transpose { ... }
1;
package Point2D;
use strict;
use parent qw(Point PlanarObject);
sub new { ... }
sub polar_coordinates { ... }
1;
The method resolution works as follows:
The starting point is defined by the left operand of the arrow operator.
If it is a bare word:
Point2D->new(...);
...or a scalar variable holding a string:
my $class = 'Point2D';
$class->new(...);
...then the starting point is the package with the corresponding name (Point2D
in both examples).
If the left operand is a scalar variable holding a blessed reference:
my $point = {...};
bless $point, 'Point2D'; # typically, it is encapsulated into class methods
my @coord = $point->polar_coordinates;
then the starting point is the class of the reference (again, Point2D
). The arrow operator cannot be used to call methods for unblessed references.
If the starting point contains the required method, it is simply called.
Thus, since Point2D::new
exists,
Point2D->new(...);
will simply call it.
If the starting point does not contain the required method, depth-first search in the parent
classes is performed. In the example above, the search order will be as follows:
Point2D
Point
(first parent of Point2D
)GeometryObject
(parent of Point
)PlanarObject
(second parent of Point2D
)For example, in the following code:
my $point = Point2D->new(...);
$point->transpose(...);
the method that will be called is GeometryObject::transpose
, even though it would be overridden in PlanarObject::transpose
.
You can set the starting point explicitly.
In the previous example, you can explicitly call PlanarObject::transpose
like so:
my $point = Point2D->new(...);
$point->PlanarObject::transpose(...);
In a similar manner, SUPER::
performs method search in parent classes of the current class.
For example,
package Point2D;
use strict;
use parent qw(Point PlanarObject);
sub new {
(my $class, $x, $y) = @_;
my $self = $class->SUPER::new;
...
}
1;
will call Point::new
in the course of the Point2D::new
execution.