Object-Oriented Programming


Classes

  • A class is a package that provides methods to deal with object references
  • There's no special syntax for class definitions

Objects

  • An object is a reference that knows which class it belongs to (that's been "blessed")

Methods

  • A method is a subroutine that expects an object reference (or a package name, for class methods) as the first argument
  • There's no special syntax for method definitions

Class methods

  • The first argument is a class name (which is often ignored by the method)
sub foo {
my $class = shift;
...
}
sub foo {
my ($class, @args) = @_;
...
}
# The following two class method calls are roughly equivalent
MyClass->foo($str);
MyClass::foo("MyClass", $str);

Instance methods

  • The first argument is an object reference
sub bar {
my $self = shift;
...
}
# The following two instance method calls are roughly equivalent
$obj->bar($str);
MyClass::bar($obj, $str);

Constructor

sub new {...}
  • A constructor is a subroutine that returns a reference to something "blessed" into a class
  • The object is what has been "blessed", not the reference
  • new is not a reserved word; a different name can be used for the constructor (i.e. spawn)
  • There's no special syntax for constructors
# Short syntax
sub new { bless {} }
# Longer syntax
sub new {
my $self = {};
bless $self;
# Optionally call an initialize method here
return $self;
}
# This syntax allows the constructor to be inherited
sub new {
my $class = shift;
my $self = {};
bless ($self, $class);
# Optionally call an initialize method here
return $self;
}

Destructor

sub DESTROY {...}
  • When the last reference to an object goes away, the object is automatically destroyed
  • To run clean-up code just before the object is freed, define a DESTROY method in the class (which will be called automatically)
  • A reference (for the object in question) is the only argument passed in

Inheritance

  • Each package has an @ISA array, which lists the inherited packages (the base classes of the current class)
  • If a method is not found in the current class, the classes in @ISA are searched (depth-first, left-to-right by default)
  • Only methods are inherited (data is not)
# Calling a parent method
sub foo {
my $self = @_;
$self->SUPER::foo(@_);
}

Example 1

  • Class and instance methods
  • Simple constructor
package MyClass;   # MyClass.pm

use strict;
use warnings;

# Class methods
sub new { bless {} }
sub func1 {
my $class = shift;
print "This is func1\n";
}

# Instance methods
sub func2 {
my $self = shift;
print "This is func2\n";
}

1; # Return a true value from the file
use strict;
use MyClass;

my $obj = MyClass::new;

# Call the class method
MyClass::func1("MyClass");
$obj->func1();

# Call the instance method
MyClass::func2($obj);
$obj->func2();

Example 2

  • Class and instance data
  • Class and instance methods
  • Combined getter-setter
  • Constructor, destructor
package MyClass;   # MyClass.pm

use strict;
use warnings;

# Define class variables
my $num_objs = 0;

# Constructor
sub new {
my $class = (shift or "MyClass");
my $self = {};
bless ($self, $class);
$self->initialize;
return $self;
}

# Destructor
sub DESTROY { $num_objs--; }

# Class methods

sub count { return $num_objs; }

# Instance methods

sub initialize {
my $self = shift;
$num_objs++;

# Define instance variables
$self->{ID} = $num_objs;
$self->{NAME} = undef;
}

sub get_id { return shift->{ID}; }

# Combined getter-setter
sub name {
my $self = shift;
return (@_ ? ($self->{NAME} = shift) : $self->{NAME});
}

1; # Return a true value from the file
use strict;
use MyClass;

my $obj = MyClass::new;
print "Created object [ID = " . $obj->get_id() . "], Number of objects: " . MyClass::count . "\n";

my $obj2 = MyClass::new;
print "Created object [ID = " . $obj2->get_id() . "], Number of objects: " . $obj2->count . "\n";

$obj->name("Betty");
print "Name: " . $obj->name . "\n";

$obj = undef;
print "Freed object, Number of objects: " . MyClass::count . "\n";

$obj2 = undef;
print "Freed object, Number of objects: " . MyClass::count . "\n";