next up previous contents index
Next: A C Program Up: Objects Oriented Programming Previous: Further examples   Contents   Index


Inheritance

Another powerful feature of object-oriented programming is the concept of inheritance. This arises when once to start with some basic module and extend it, either by adding methods or by changing one of the available methods. Inheritance makes such tasks relatively easy, which thus makes your programs relatively extendable and scaleable.

Suppose in the previous example one wanted to add a method to look up in a file rgb.txt then name of the color associated with the rgb values. The format of the rgb.txt file (found on io.uwinnipeg.ca under /usr/X11R6/lib/X11/) is the following:

255 250 250             snow
248 248 255             ghost white
248 248 255             GhostWhite
245 245 245             white smoke
245 245 245             WhiteSmoke
Thus, what we want to do is read this file, find the matching rgb values, and extract the name of the color.

We could add a method to RGB4 of before to do this, but here we are going to do it by inheritance. Consider the following module:

package RGB5;
use strict;
use base qw(RGB4);

sub color_name {
    my $self = shift;
    my $rgb = $self->{rgb} or die "No rgb data available";
    open(my $fh, 'rgb.txt') or die "Cannot open rgb.txt: $!";
    my $name;
    while (my $line = <$fh>) {
        chomp $line;
        my @data = split ' ', $line, 4;
        if ($data[0] == $rgb->[0]
            and $data[1] == $rgb->[1]
            and $data[2] == $rgb->[2]) {
            $name = $data[3];
            last;
        }
    }
    return $name ? $name : 'unknown';
}

1;
which is used in a script as
use strict;
use RGB5;
my @rgb_data = (255, 0, 0);

my $obj = RGB5->new(rgb => \@rgb_data);
my $hex = $obj->rgb2hex();
print "The hex equivalent is $hex\n";
print "The color name is ", $obj->color_name(), "\n";
The magical thing here is the use of
   use base qw(RGB4);
inside of RGB5 - what this does is tells RGB5 to inherit all of the data and methods of RGB4, and so in RGB5 all we have to do is add the additional methods that we want RGB5 to have (in object-oriented lingo, RGB4 is the parent, and RGB5 is the child).

Methods not appearing explicitly within a child will be looked for within a parent. Sometimes though you may want to alter one of the parent's methods. This is straightforward - within the child you simply define the method you want. For example, suppose we want the rgb2hex method of the parent RGB4 to return the hexadecimal equivalent of an rgb triplet with a # prepended to it - this may be convenient for using the module in a web environment, where colors are specified inside of html tags in this way:

  <BODY BGCOLOR="#FFFFFF">
One way to do this is to construct a child with the desired rgb2hex method explicitly defined:
package RGB6;
use strict;
use base qw(RGB4);

sub rgb2hex {
    my $self = shift;
    return "#$self->{hex}" if $self->{hex};
    my $rgb = $self->{rgb} or die "No rgb data available";
    my $hex = sprintf("%02X%02X%02X", $rgb->[0], $rgb->[1], $rgb->[2]);
    $self->{hex} = $hex;
    return "#$hex";
}

1;
However, in this particular case there is much duplicated code - we have essentially copied all of rgb2hex of RGB4, and are just altering the return value. A better approach here would be to use SUPER to call the parent's rgb2hex method, and then make the desired adjustments:
package RGB6;
use strict;
use base qw(RGB4);

sub rgb2hex {
    my $self = shift;
    my $hex = $self->SUPER::rgb2hex();
    return "#$hex";
}

1;
This ability to easily adjust methods makes inheritance one of the most useful aspects of object-oriented programming.


next up previous contents index
Next: A C Program Up: Objects Oriented Programming Previous: Further examples   Contents   Index