Wednesday, September 19, 2007

Creating classes and objects

It's important to understand the difference between classes and objects.

A class is a description (or template) of the data and methods accessible through its objects. An object is an instance of a class. Thus the class of humans describes humans as having the attributes: hands, arms, legs, heads, hair and methods: talk, think, eat, sit. However each human is an instance of the human class, an object. Each of us have different hands, arms, legs, heads and hair. But if I can jump, it's because humans can jump. That is, the class defines the methods and attributes for each object belonging to that class.

Classes

A class in Perl is just a package. Thus to create a PlayingCard class we write:

    package PlayingCard;

Now we have a PlayingCard class.

Constructors and class methods

A class method is a subroutine which performs operations on behalf of the class rather than on a specific object. It may create or copy an object, keep track of relevant statistics or many other class based things.

The most common class method is the constructor method. This allows us to create new objects and thus is traditionally called new (although this is neither required nor universal).

    package PlayingCard;    # This creates our class

sub new {

}

We call the new method like this:

    my $card = PlayingCard->new(9, 'hearts');

We have to call our constructor function with the class name, because this allows Perl to distinguish between calls to PlayingCard's new function and another class's new function. Doing so provides the new function with the class name as its first argument. Thus we have:

    sub new {
my ($class_name, $value, $suit) = @_;

}

Creating an object

Creating an object in Perl is a two step process. First we need to take a reference to the data structure upon which we'll base our object. It's possible to use arrays, hashes, scalars, and even more exotic constructs, but most Perl objects are based on hashes.

The process of turning turning a reference into an object is called 'blessing', and we use Perl's bless() function to turn our reference into an object of the required class.

    sub new {
my ($class_name, $value, $suit) = @_;

# Create an anonymous hash with our values
# and refer to it through the $card variable.
my $card = {
value => $value,
suit => $suit
};

# This turns $card into a PlayingCard object
bless($card, $class_name);

return $card;
}

Now $card will be a PlayingCard object upon which we can call methods.

We use $class_name here rather than "PlayingCard" as this allows us flexibility in the future. Should our class's name change, for example, we can limit the number of places we need to change the code. This is also very important should we wish to inherit from our class in the future.

Methods

A method is just a subroutine inside the class which performs operations on an object of that class.

    # Get suit returns the card's (object's) suit.
# This is a method

sub get_suit {
# Code here to return the card's suit
}

To call a method on an object we use the arrow (->) operator.

    print "I have a card of suit: ";
print $card->get_suit();

In the same way that calling a class method provides the class name as the first argument; calling an object method provides the object as the first argument.

Thus we have:

    # get suit returns the card's (object's) suit.
sub get_suit {
my ($card) = @_;

}

As our card is a reference to a hash, we just do a hash lookup:

    # get suit returns the card's (object's) suit.
sub get_suit {
my ($card) = @_;

return $card->{suit};
}

Conclusion

That's all there is to the basics of creating classes and objects in Perl. From here there's inheritance, destructor functions, abstract classes, polymorphism, operator overloading and much more. All of which make Perl's OO system very powerful and very flexible. If you want to learn more about these then consider Perl Training Australia's "Object Oriented Perl" and "Advanced Object Oriented Perl" courses.

Next week we will discuss when to consider using OO in your projects.