个性化阅读
专注于IT技术分析

Perl对象概念:面向对象编程

本文概述

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

Perl基本对象

一个对象只是一个数据结构, 它知道它所属的类名。它作为参考存储在标量变量中。相同的标量变量可以保存不同类中的不同对象, 因为它仅保存对对象的引用。

一个类就是一个包。它包含对对象进行操作(创建和操作)的方法。

方法是一个子例程, 该例程将对象引用或程序包名称作为第一个参数。


Perl类声明

要创建一个类, 我们需要在Perl中创建一个包。程序包包含可以重用的变量和子例程。

由于每个类都是一个包, 因此它具有自己的名称空间, 该名称空间由符号名称组成。类是使用package关键字创建的名称空间。通常在与类同名的模块中实现。例如, My ::文件将在File.pm文件中实现, 位置将是目录My, 其内容如下。

package My::File;
use strict;
use warnings;
1;

此处的末尾1表示文件已成功加载。

包的范围扩展到文件末尾, 或者直到遇到另一个包关键字。


Perl构造函数

代码需要一个功能完整的类的构造函数。

通常, 构造函数是作为新方法实现的。

sub new {
    my ($class, %args) = @_;
    return bless \%args, $class;
}

Perl实例/对象

实例或对象主要是对哈希的祝福引用。祝福某事意味着我们祝福该变量所指的事物。

use Scalar::Util 'blessed';
  my $Ana = {};
  my $Christian = $Ana;
  bless $Ana, 'Happiness';
  print blessed( $Christian ) // 'not blessed';    # Class
  print "\n";
  $Christian = "some other value";
  print blessed( $Christian ) // 'not blessed';    # not blessed
  print "\n";

输出

Class
not blessed

在上面的程序中, 当我们对变量调用”保佑”时, 我们保佑变量所引用的数据结构。参考没有得到祝福。因此, 当我们第二次调用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};
}

步骤2在student.pm文件中, 编写Student package和helper函数。

#!/usr/bin/perl 
package Student;
sub new	
{
    my $class = shift;
    my $self = {
        _name => shift, _rank  => shift, };
    # Print all 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子例程。
  • 如果仍然找不到方法, 它将使用UNIVERSAL类进行搜索, 该类是标准Perl库的一部分。
  • 如果仍然找不到, 则会发生运行时异常。

也可以使用父指令声明继承, 该指令取代了较早的基本指令。

例:

我们的脚本加载一个模块, 调用其构造函数, 然后调用两个方法。

使用以下脚本创建hw.pl文件。在这里, 模块本身使用父指令声明其继承。

#!/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调用新方法时, Perl不会在Module1中找到它。它将在继承链中的下一个模块Module2中查找它。因此, 将从Module2中调用新方法。


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继承的子类。

赞(0)
未经允许不得转载:srcmini » Perl对象概念:面向对象编程

评论 抢沙发

评论前必须登录!