Perl教程
Perl控制语句
Perl高级

Perl 对象概念

Perl 对象概念

Perl 为我们提供了一些构建面向对象系统的工具。 Perl 面向对象的概念基于引用、匿名数组和散列。

Perl 基本对象

对象只是一种数据结构,它知道它所属的类名。它作为引用存储在标量变量中。同一个标量变量可以在不同的类中保存不同的对象,因为它只保存对对象的引用。
类 只是一个包。它包含对对象进行操作(创建和操作它)的方法。
方法 是一个子程序,它需要一个对象引用或一个包名作为第一个参数。

Perl 类声明

要创建一个类,我们需要在 Perl 中创建一个包。包包含可以重用的变量和子例程。
因为每个类都是一个包,所以它有自己的命名空间,由符号名称组成。类是使用 package 关键字创建的命名空间。它一般在与类同名的模块中实现。例如,My:: File 将在文件 File.pm 中实现,位置将是具有以下内容的目录 My。
package My::File;
use strict;
use warnings;
1;
这里末尾的 1 表示文件加载成功。
包的范围扩展到文件末尾或直到遇到另一个包关键字。

Perl 构造函数

代码需要一个全功能类的构造函数。
大多数情况下,构造函数被实现为 new 方法。
sub new {
    my ($class, %args) = @_;
    return bless \%args, $class;
}

Perl 实例/对象

实例或对象是主要对散列的祝福引用。祝福某事意味着我们祝福变量所指的事物。
use Scalar::Util 'blessed';
  my $Ana = {};
  my $Christian = $Ana;
  bless $Ana, 'Happiness';
  printblessed( $Christian ) // 'not blessed';    # Class
  print"\n";
  $Christian = "some other value";
  printblessed( $Christian ) // 'not blessed';    # not blessed
  print"\n";  
输出:
Class
not blessed
在上面的程序中,当我们对一个变量调用'bless'时,我们正在祝福变量所指的数据结构。参考没有得到祝福。因此,当我们第二次调用blessed($Christian) 时,它返回false。因为 $Christian 没有存储对对象的引用。

Perl 析构函数

Perl 析构函数用于在不再需要时清理分配给对象的内存。当对象超出范围时,它会在 Perl 中自动完成。所以它通常不在 Perl 中实现。
为了实现析构函数,有一个函数叫做 DESTROY。它在对象被销毁和 Perl 回收内存之前调用。
package MyExample;
sub DESTROY {
   my ($self) = @_;
   print"MyExample::DESTROY called\n";
}

Perl 定义方法

在 Perl 中没有定义方法的特殊语法。它只是一个用'sub'关键字声明的普通子程序。
一个方法需要一个对象或一个类名作为它的第一个参数。
调用一个方法,使用->操作符。
调用一个方法作为一个对象,使用以下语法:
$object-> method
左侧是对象名称,右侧是方法名称。
调用方法时,左侧对象作为第一个参数传递到右侧。
示例:
在这个示例中,我们将设置一个辅助方法和一个辅助函数来设置学生的姓名和排名。
步骤 1 在 hw.pl 文件中,定义一个辅助方法 studentName 以获取学生姓名。
定义一个辅助函数 studentRank 来获取学生的排名。
sub studentName {
    return $self->{_name};
}
sub studentRank {
    my ( $self, $name ) = @_;
    $self->{_name} = $name if defined($name);
    return $self->{_name};
}
Step 2 在student.pm文件中,编写Student包和辅助函数。
#!/usr/bin/perl 
package Student;
sub new 
{
    my $class = shift;
    my $self = {
        _name => shift,
        _rank  => shift,   
    };
    # Printall the values just for clarification.
    print"Student's name is $self->{_name}\n";
    print"Student's rank is $self->{_rank}\n";
    
    bless $self, $class;
    return $self;
}
sub studentRank {
    my ( $self, $name ) = @_;
    $self->{_name} = $name if defined($name);
    return $self->{_name};
}
sub studentName {
    my( $self ) = @_;
    return $self->{_name};
}
1;
步骤 3 在 person.pl 文件中,我们将使用 Student 对象来获取输出。
#!/usr/bin/perl
use Student;
$object = new Student( "Ana", "9th");
# name which is set using constructor.
$name = $object->studentName();
print"Name set using constructor is : $name\n";
# name set using helper function.
$object->studentRank( "Anastasia" );
# getting name set by helper function.
$name = $object->studentName();
print"Name set using helper is : $name\n";
输出:
Student's name is Ana
Student's rank is 9th
Name set using constructor is : Ana
Name set using helper is : Anastasia

Perl 继承

继承意味着子类将继承父类的属性和方法。因此,要重用代码,您可以简单地继承它。在 Perl 中,@ISA 数组定义了继承。
在使用继承时,应考虑以下几点:
它将搜索给定方法的对象类,即;变量。 它搜索在对象类的@ISA 数组中定义的类。 如果在上述步骤中未找到任何方法,则使用 AUTOLOAD 子例程。 如果没有找到 Still 方法,它会使用 UNIVERSAL 类进行搜索,该类是标准 Perl 库的一部分。 如果仍未找到,则发生运行时异常。
也可以使用 parent 指令来声明继承,该指令替换旧的基本指令。
示例:
我们的脚本加载一个模块,调用它的构造函数,然后调用两个方法。
使用以下脚本创建hw.pl文件。在这里,模块本身使用 parent 指令声明其继承。
#!/usr/bin/perl
use strict;
use warnings;
use Module1;
my $myObj = Module1->new;
$myObj->setHello;
$myObj->setBye;
输出:
this is Hello message from Module1
this is Bye message from Module2
使用以下脚本创建Module1.pm 文件。它声明了我们继承构造函数和另一个方法的模块。
package Module1;
use strict;
use warnings;
use parent 'Module2';
sub setHello {
    print"this is Hello message from Module1\n";
}
1;
使用以下脚本创建Module2.pm文件。
package Module2;
use strict;
use warnings;
sub new {
    my ($class) = @_;
    return bless {}, $class;
} 
sub setBye {
    my ($self) = @_;
    print"this is Bye message from Module2\n";
    return;
}
1;
在从 Module1 调用 new 方法时,Perl 不会在 Module1 中找到它。它将在继承链中的下一个模块 Module2 中查找它。因此,将从 Module2 调用 new 方法。

Perl 多态

多态意味着基类中定义的方法将覆盖父类中定义的方法。
它附加了现有的功能无需对整个班级重新编程。
示例:
package A;
    sub A1 {
        print("Inside A::A1\n");
    }
package B;
    @ISA = (A);
    sub A1 {
        print("Inside B::B1\n");
    }
package main;
    B->A1();
输出:
Inside B::B1
在 B 类中定义的子 A1 覆盖了从 A 类继承的。
昵称: 邮箱:
Copyright © 2022 立地货 All Rights Reserved.
备案号:京ICP备14037608号-4