Perl is object-oriented

There are two different implementations of object-oriented programming in Perl:

  • One is based on an anonymous hash table, and the essence of each object instance is a reference to an anonymous hash table. In this anonymous hash table, all instance properties are stored.
  • Second, in an array-based manner, when defining a class, we create an array for each instance property, and the essence of each object instance is a reference to a row index in those arrays. In these arrays, all instance properties are stored.

Object-oriented basic concepts

Object-oriented has many basic concepts, and here we receive three: objects, classes, and methods.

  • Object: An object is a reference to a data item in a class.

  • Class: A class is a Perl package that contains a class that provides an object method.

  • Method: The method is a Perl sub-program, and the class name is its first argument.

Perl provides the bless() function, which is used to construct an object, by using bless to associate a reference with the class name, and returning that reference to construct an object.


The definition of the class

A class is just a simple package.

You can use a package as a class, and the function in the package as a method of the class.

Perl's packages provide a separate namespace, so the methods and variable names of different packages do not conflict.

The file suffix for the Perl class is .pm.

Next we create a Person class:

package Person;

The class's code ranges to the last line of the script file, or to the next package keyword.


Create and use objects

To create an instance (object) of a class, we need to define a constructor, and most programs use class names as constructors, and any name can be used in Perl.

You can use a variety of Perl variables as perl objects. In most cases we use reference arrays or hashes.

Next we create a constructor for the Person class, using a hash reference to Perl.

When you create an object, you need to provide a constructor, which is a sub-program that returns a reference to the object.

Here's an example:

package Person;
sub new
{
    my $class = shift;
    my $self = {
        _firstName => shift,
        _lastName  => shift,
        _ssn       => shift,
    };
    # 输出用户信息
    print "名字:$self->{_firstName}\n";
    print "姓氏:$self->{_lastName}\n";
    print "编号:$self->{_ssn}\n";
    bless $self, $class;
    return $self;
}

Next we create an object:

$object = new Person( "小明", "王", 23234345);

Define the method

The method of the Perl class is only a Perl sub-program, commonly referred to as a member function.

Perl's method definition in object-oriented does not provide any special syntax, but specifies that the first argument of the method is the object or the package to which it is referenced.

Perl does not provide private variables, but we can manage object data in a secondary way.

Next we define a way to get a name:

sub getFirstName {
    return $self->{_firstName};
}

The same can be said:

sub setFirstName {
    my ( $self, $firstName ) = @_;
    $self->{_firstName} = $firstName if defined($firstName);
    return $self->{_firstName};
}

Next, let'Person.pm the code for the file, as follows:

#!/usr/bin/perl 

package Person;

sub new
{
    my $class = shift;
    my $self = {
        _firstName => shift,
        _lastName  => shift,
        _ssn       => shift,
    };
    # 输出用户信息
    print "名字:$self->{_firstName}\n";
    print "姓氏:$self->{_lastName}\n";
    print "编号:$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;

employee.pl script code is as follows:

#!/usr/bin/perl

use Person;

$object = new Person( "小明", "王", 23234345);
# 获取姓名
$firstName = $object->getFirstName();

print "设置前姓名为 : $firstName\n";

# 使用辅助函数设置姓名
$object->setFirstName( "小强" );

# 通过辅助函数获取姓名
$firstName = $object->getFirstName();
print "设置后姓名为 : $firstName\n";

After performing the above procedure, the output is:

$ perl employee.pl
名字:小明
姓氏:王
编号:23234345
设置前姓名为 : 小明
设置后姓名为 : 小强

Inherited

The Class method in Perl @ISA an array that contains the names of other packages (classes), and the inheritance of variables must be explicitly set.

Multi-inheritance is @ISA array contains multiple class (package) names.

By @ISA you can only inherit methods, not data.

Next we create an Employee class to inherit the Person class.

Employee.pm file code looks like this:

#!/usr/bin/perl

package Employee;
use Person;
use strict;
our @ISA = qw(Person);    # 从 Person 继承

Now that the Employee class contains all the methods and properties of the Person class, we enter the following code in the main.pl file and execute:

#!/usr/bin/perl

use Employee;

$object = new Employee( "小明", "王", 23234345);
# 获取姓名
$firstName = $object->getFirstName();

print "设置前姓名为 : $firstName\n";

# 使用辅助函数设置姓名
$object->setFirstName( "小强" );

# 通过辅助函数获取姓名
$firstName = $object->getFirstName();
print "设置后姓名为 : $firstName\n";

After performing the above procedure, the output is:

$ perl main.pl
名字:小明
姓氏:王
编号:23234345
设置前姓名为 : 小明
设置后姓名为 : 小强

Method override

In the above example, the Employee class inherits the Person class, but if the Method of the Person class does not meet the requirements, it needs to be rewritten.

Next, let's add some new methods to the Employee class and rewrite the Methods for the Person class:

#!/usr/bin/perl

package Employee;
use Person;
use strict;
our @ISA = qw(Person);    # 从 Person 继承

# 重写构造函数
sub new {
    my ($class) = @_;

    # 调用父类的构造函数
    my $self = $class->SUPER::new( $_[1], $_[2], $_[3] );
    # 添加更多属性
    $self->{_id}   = undef;
    $self->{_title} = undef;
    bless $self, $class;
    return $self;
}

# 重写方法
sub getFirstName {
    my( $self ) = @_;
    # 这是子类函数
    print "这是子类函数\n";
    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 main.pl the following code in the file and execute:

#!/usr/bin/perl

use Employee;

$object = new Employee( "小明", "王", 23234345);
# 获取姓名,使用修改后的构造函数
$firstName = $object->getFirstName();

print "设置前姓名为 : $firstName\n";

# 使用辅助函数设置姓名
$object->setFirstName( "小强" );

# 通过辅助函数获取姓名
$firstName = $object->getFirstName();
print "设置后姓名为 : $firstName\n";

After performing the above procedure, the output is:

$ perl main.pl
名字:小明
姓氏:王
编号:23234345
这是子类函数
设置前姓名为 : 小明
这是子类函数
设置后姓名为 : 小强

Loaded by default

If the requested method is not found in the current class, all the base classes of the current class, and in the UNIVERSAL class, a method named AUTOLOAD() is looked up again. I f AUTOLOAD is found, it is called and the value of $AUTOLOAD is set as the fully qualified name of the missing method.

If not, Perl fails and makes a mistake.

If you don't want to inherit autoLOAD from the base class, it's simple, just one sentence:

sub AUTOLOAD;

Destructors and garbage collection

When the last reference to the object is released, the object is automatically destructed.

If you want to do something when destructing, you can define a method called DESTROY in the class. It will be called automatically at the right time and perform additional cleanup actions as you want.

package MyClass;
...
sub DESTROY
{
    print "MyClass::DESTROY called\n";
}

Perl passes the object's reference to DESTROY as a unique argument. N ote that this reference is read-only, which means that you can't modify it by accessing $[ ( see perlsub) but the object itself (e.g. "$" or "

If you re-bless the object reference before the destructor returns, Perl calls the DESTROY method of the object that you re-bless after the destructor returns. T his gives you the opportunity to call the destructor of the base class or other classes that you specify. I t should be noted that DESTROY can also be called manually, but it is usually not necessary to do so.

When the current object is released, other objects contained in the current object are automatically released.


Perl object-oriented instances

We can further understand Perl object-oriented applications by following examples:

#!/usr/bin/perl

# 下面是简单的类实现
package MyClass;

sub new
{
   print "MyClass::new called\n";
   my $type = shift;            # 包名
   my $self = {};               # 引用空哈希
   return bless $self, $type;   
}

sub DESTROY
{
   print "MyClass::DESTROY called\n";
}

sub MyMethod
{
   print "MyClass::MyMethod called!\n";
}


# 继承实现
package MySubClass;

@ISA = qw( MyClass );

sub new
{
   print "MySubClass::new called\n";
   my $type = shift;            # 包名
   my $self = MyClass->new;     # 引用空哈希
   return bless $self, $type;  
}

sub DESTROY
{
   print "MySubClass::DESTROY called\n";
}

sub MyMethod
{
   my $self = shift;
   $self->SUPER::MyMethod();
   print "   MySubClass::MyMethod called!\n";
}

# 调用以上类的主程序
package main;

print "调用 MyClass 方法\n";

$myObject = MyClass->new();
$myObject->MyMethod();

print "调用 MySubClass 方法\n";

$myObject2 = MySubClass->new();
$myObject2->MyMethod();

print "创建一个作用域对象\n";
{
  my $myObject2 = MyClass->new();
}
# 自动调用析构函数

print "创建对象\n";
$myObject3 = MyClass->new();
undef $myObject3;

print "脚本执行结束...\n";
# 自动执行析构函数

The above procedure is performed and the output is:

调用 MyClass 方法
MyClass::new called
MyClass::MyMethod called!
调用 MySubClass 方法
MySubClass::new called
MyClass::new called
MyClass::MyMethod called!
   MySubClass::MyMethod called!
创建一个作用域对象
MyClass::new called
MyClass::DESTROY called
创建对象
MyClass::new called
MyClass::DESTROY called
脚本执行结束...
MyClass::DESTROY called
MySubClass::DESTROY called