Perl Object Oriented
There are two different implementations of object-oriented programming in Perl:
* One is based on anonymous hash tables, where the essence of each object instance is a reference to an anonymous hash table. All instance attributes are stored in this anonymous hash table.
* The other is based on arrays. When defining a class, we create an array for each instance attribute, and the essence of each object instance is a reference to a specific index in these arrays. All instance attributes are stored in these arrays.
* * *
## Basic Concepts of Object-Oriented Programming
Object-oriented programming has many basic concepts. Here we introduce three: objects, classes, and methods.
* **Object**: An object is a reference to data items within a class.
* **Class**: A class is a Perl package that contains methods for providing objects.
* **Method**: A method is a Perl subroutine, with the class name as its first argument.
Perl provides the `bless()` function. `bless` is used to construct objects. It associates a reference with a class name and returns that reference to construct an object.
* * *
## Class Definition
A class is simply a package.
A package can be used as a class, and functions within the package can be used as class methods.
Perl packages provide separate namespaces, so method and variable names from different packages do not conflict.
Perl class files have the `.pm` extension.
Next, we create a `Person` class:
```perl
package Person;
The scope of the class extends to the last line of the script file or until the next `package` keyword.
* * *
## Creating and Using Objects
To create an instance (object) of a class, we need to define a constructor. Most programs use the class name as the constructor, but in Perl, any name can be used.
You can use various Perl variables as Perl objects. In most cases, we use references to arrays or hashes.
Next, we create a constructor for the `Person` class using a Perl hash reference.
When creating an object, you need to provide a constructor, which is a subroutine that returns a reference to the object.
Example:
## Example
```perl
package Person;
sub new {
my $class = shift;
my $self = {
_firstName => shift,
_lastName => shift,
_ssn => shift,
};
print "First Name:$self->{_firstName}n";
print "Last Name:$self->{_lastName}n";
print "ID:$self->{_ssn}n";
bless $self, $class;
return $self;
}
Next, we create an object:
```perl
$object = new Person( "Xiao Ming", "Wang", 23234345);
* * *
## Defining Methods
Perl class methods are just Perl subroutines, commonly known as member functions.
In Perl's object-oriented programming, method definition does not provide any special syntax, but it is specified that the first argument of a method is the object or the package it is referenced from.
Perl does not provide private variables, but we can manage object data through auxiliary means.
Next, we define a method to get the first name:
```perl
sub getFirstName {
return $self->{_firstName};
}
It can also be written as:
```perl
sub setFirstName {
my ( $self, $firstName ) = @_;
$self->{_firstName} = $firstName if defined($firstName);
return $self->{_firstName};
}
Next, we modify the code in the `Person.pm` file as follows:
## Example
```perl
#!/usr/bin/perl
package Person;
sub new {
my $class = shift;
my $self = {
_firstName => shift,
_lastName => shift,
_ssn => shift,
};
print "First Name:$self->{_firstName}n";
print "Last Name:$self->{_lastName}n";
print "ID:$self->{_ssn}n";
bless $self, $class;
return $self;
}
sub setFirstName {
my ($self, $firstName) = @_;
$self->{_firstName} = $firstName if defined($firstName);
return $self->{_firstName};
}
sub getFirstName {
my ($self) = @_;
return $self->{_firstName};
}
1;
The `employee.pl` script code is as follows:
## Example
```perl
#!/usr/bin/perl
use Person;
$object = new Person("Xiao Ming", "Wang", 23234345);
$firstName = $object->getFirstName();
print "Name before setting is : $firstNamen";
$object->setFirstName("Xiao Qiang");
$firstName = $object->getFirstName();
print "Name after setting is : $firstNamen";
After executing the above program, the output is:
$ perl employee.pl
First Name: Xiao Ming
Last Name:Wang
ID: 23234345
Name before setting is : Xiao Ming
Name after setting is : Xiao Qiang
* * *
## Inheritance
In Perl, class methods are inherited through the `@ISA` array, which contains the names of other packages (classes). Variable inheritance must be explicitly set.
Multiple inheritance means that the `@ISA` array contains multiple class (package) names.
Only methods can be inherited through `@ISA`, not data.
Next, we create an `Employee` class that inherits from the `Person` class.
The `Employee.pm` file code is as follows:
## Example
```perl
#!/usr/bin/perl
package Employee;
use Person;
use strict;
our @ISA = qw(Person);
Now the `Employee` class contains all methods and attributes of the `Person` class. We enter the following code in the `main.pl` file and execute it:
## Example
```perl
#!/usr/bin/perl
use Employee;
$object = new Employee("Xiao Ming", "Wang", 23234345);
$firstName = $object->getFirstName();
print "Name before setting is : $firstNamen";
$object->setFirstName("Xiao Qiang");
$firstName = $object->getFirstName();
print "Name after setting is : $firstNamen";
After executing the above program, the output is:
$ perl main.pl
First Name: Xiao Ming
Last Name:Wang
ID: 23234345
Name before setting is : Xiao Ming
Name after setting is : Xiao Qiang
* * *
## Method Overriding
In the example above, the `Employee` class inherits from the `Person` class. However, if the methods of the `Person` class do not meet the requirements, their methods need to be overridden.
Next, we add some new methods to the `Employee` class and override the methods of the `Person` class:
## Example
```perl
#!/usr/bin/perl
package Employee;
use Person;
use strict;
our @ISA = qw(Person);
sub new {
my($class) = @_;
my $self = $class->SUPER::new($_, $_, $_);
$self->{_id} = undef;
$self->{_title} = undef;
bless $self, $class;
return $self;
}
sub getFirstName {
my($self) = @_;
print "This is a subclass function";
return $self->{_firstName};
}
sub setLastName {
my($self, $lastName) = @_;
$self->{_lastName} = $lastName if defined($lastName);
return $self->{_lastName};
}
sub getLastName {
my($self) = @_;
return $self->{_lastName};
}
1;
We enter the following code in the `main.pl` file and execute it:
## Example
```perl
#!/usr/bin/perl
use Employee;
$object = new Employee("Xiao Ming", "Wang", 23234345);
$firstName = $object->getFirstName();
print "Name before setting is : $firstNamen";
$object->setFirstName("Xiao Qiang");
$firstName = $object->getFirstName();
print "Name after setting is : $firstNamen";
After executing the above program, the output is:
$ perl main.pl
First Name: Xiao Ming
Last Name:Wang
ID: 23234345
This is a subclass function
Name before setting is : Xiao Ming
This is a subclass function
Name after setting is : Xiao Qiang
* * *
## Default Loading
If the requested method cannot be found in the current class, all base classes of the current class, and the `UNIVERSAL` class, then a method named `AUTOLOAD()` will be searched for again. If `AUTOLOAD` is found, it will be called, and the global variable `$AUTOLOAD` will be set to the fully qualified name of the missing method.
If that still fails, Perl will declare failure and throw an error.
If you do not want to inherit the `AUTOLOAD` from the base class, it's simple, just one line:
```perl
sub AUTOLOAD;
* * *
## Destructors and Garbage Collection
When the last reference to an object is released, the object is automatically destroyed.
If you want to do something during destruction, you can define a method named `DESTROY` in the class. It will be called automatically at the appropriate time and perform additional cleanup actions as you intend.
```perl
package MyClass;
...
sub DESTROY {
print "MyClass::DESTROY calledn";
}
Perl passes the object's reference as the sole argument to `DESTROY`. Note that this reference is read-only, meaning you cannot modify it by accessing `$_`. (Translator's note: see `perlsub`). However, the object itself (e.g., `"${$_}"` or `"@{$_}"` and `"%{$_}"` etc.) is still writable.
If you re-bless the object reference before the destructor returns, Perl will call the `DESTROY` method of the object you re-blessed after the destructor returns. This gives you the opportunity to call the destructor of the base class or another class you specify. It should be noted that `DESTROY` can also be called manually, but it is usually not necessary to do so.
After the current object is released, other objects contained within the current object are automatically released.
* * *
## Perl Object-Oriented Example
We can further understand the application of Perl object-oriented programming through the following example:
## Example
```perl
#!/usr/bin/perl
package MyClass;
sub new {
print "MyClass::new calledn";
my $type = shift;
my $self = {};
return bless $self, $type;
}
sub DESTROY {
print "MyClass::DESTROY calledn";
}
sub MyMethod {
print "MyClass::MyMethod called!n";
}
package MySubClass;
@ISA = qw( MyClass );
sub new {
print "MySubClass::new calledn";
my $type = shift;
my $self = MyClass->new;
return bless $self, $type;
}
sub DESTROY {
print "MySubClass::DESTROY calledn";
}
sub MyMethod {
my $self = shift;
$self->SUPER::MyMethod();
print " MySubClass::MyMethod called!n";
}
package main;
print "Calling MyClass methodn";
$myObject = MyClass->new();
$myObject->MyMethod();
print "Calling MySubClass method";
$myObject2 = MySubClass->new();
$myObject2->MyMethod();
print "Creating a scoped objectn";
{
my $myObject2 = MyClass->new();
}
print "Create Objectn";
$myObject3 = MyClass->new();
undef $myObject3;
print "Script execution completed...n";
Executing the above program, the output is:
Calling MyClass method
MyClass::new called
MyClass::MyMethod called!
Calling MySubClass method
MySubClass::new called
MyClass::new called
MyClass::MyMethod called!
MySubClass::MyMethod called!
Creating a scoped object
MyClass::new called
MyClass::DESTROY called
Create Object
MyClass::new called
MyClass::DESTROY called
Script execution completed...
MyClass::DESTROY called
MySubClass::DESTROY called
YouTip