Perl – 面向对象编程中的属性
在 Perl 中,面向对象的概念非常基于引用和Arrays/Hashes 。与 Perl 编程相关的面向对象编程的几个主要术语是对象、类和方法。
- 在 Perl 中,对象就像对知道它所属的类的数据类型的引用。该对象存储为标量变量中存在的引用。而且由于标量只包含对对象的引用,它甚至可以保存存在于不同类中的不同对象。
- 在 Perl 中,包含创建和操作对象所需的相应方法的包称为类。
- 在 Perl 中,该方法是在包中定义的子例程。包名称或对象引用是方法的第一个参数,具体取决于方法是否影响当前类或对象。
属性
每个类都可以定义属性。当我们将它们表示为对象时,我们为这些属性赋值。例如,甚至每个“文件”对象都有一个路径。属性也称为属性。
属性通常定义为只读或读写。只读属性只能在创建对象时设置,而读写属性可以随时更改。属性的值本身可以是另一个对象。并不是每个类都有属性和方法。
Perl 没有属性的特殊语法。在后面,属性通常作为键存储在对象的底层哈希中。
Perl
sub new{
my ($class, $args) = @_;
my $self = bless { serial => $args->{serial},
name => $args->{name},
price => $args->{price}
}, $class;
}
Perl
sub new{
sub new{
my ($class, $args) = @_;
my $self = {
name => $args->{name} || ‘iPhone XR’,
price => $args->{price} || ‘52K’,
},
Return bless $self, $class;
}
1;
Perl
package Person;
use strict;
use warnings;
sub new {
my ($class, %args) = @_;
my $self = \%args;
bless $self, $class;
return $self;
}
sub name {
my ($self, $value) = @_;
if (@_ == 2)
{
$self->{name} = $value;
}
return $self->{name};
}
1;
# Assigning the object 'Person'
# to the $teacher variable.
my $teacher = Person->new;
# Setting the attribute 'name'
# to the variable '$teacher'
$teacher->name('Foo');
printf $teacher->name;
每当我们调用 new() 方法时,Perl 会自动将类名作为第一个参数传递给特殊数组 @_。
当我们创建一个对象时,我们实际上创建了一个知道它所属的类的引用。 bless(这是一个内置函数)用于bless对类的引用,然后返回该类的一个实例。在上面的示例中,我们将哈希引用传递给 bless()函数。但是可以将任何类型的引用传递给 bless函数,例如数组引用,这使得使用哈希引用变得更加容易。
创建默认属性值
现在我们可以知道如何应用属性了。但是,如果我们不传递 Perl 程序中的所有参数,会发生什么?在这种情况下,属性将被对象初始化为“null”。因此,有一种方法可以通过设置默认值来避免这种情况,如果在构造对象时存在参数,则这些默认值会被覆盖。逻辑或运算符||可以用来达到这个效果。
Perl
sub new{
sub new{
my ($class, $args) = @_;
my $self = {
name => $args->{name} || ‘iPhone XR’,
price => $args->{price} || ‘52K’,
},
Return bless $self, $class;
}
1;
访问属性
访问属性的最佳方式是通过访问器方法。这些方法可以帮助我们在 Perl 中获取或设置每个属性的值。
两种类型的访问器是:
- Getter:获取属性的值。
- Setter(也称为 Mutator):它设置属性值。
Perl
package Person;
use strict;
use warnings;
sub new {
my ($class, %args) = @_;
my $self = \%args;
bless $self, $class;
return $self;
}
sub name {
my ($self, $value) = @_;
if (@_ == 2)
{
$self->{name} = $value;
}
return $self->{name};
}
1;
# Assigning the object 'Person'
# to the $teacher variable.
my $teacher = Person->new;
# Setting the attribute 'name'
# to the variable '$teacher'
$teacher->name('Foo');
printf $teacher->name;
Foo
我们在这里调用构造函数Person->new,它返回一个我们分配给$teacher的对象,然后我们调用访问器$teacher->name('Foo') ,通过提供一个值然后使用它作为setter与getter $teacher->name相同的访问器(不传递值)使其在使用称为“name”的相同方法时获取属性的当前值。
当我们调用$teacher->name('Foo')时,Perl 会注意到$teacher 是对哈希的祝福引用,并且它被祝福到 Person(名称空间)中。如果没有祝福引用,它就不会知道如何处理箭头和之后的“名称”,并且会抛出异常:(无法调用方法 .. on unblessed reference)
好吧,既然它被祝福到 Person 命名空间,Perl 将开始在 Person 命名空间中寻找“name”函数,一旦找到该函数,Perl 将使用我们传递的参数调用该函数它,但它也会接受我们在箭头左侧的变量并将其作为第一个参数传递。 (在我们的例子中是 $teacher)。
在我们的示例中,这个“name”函数在我们向它传递值时被称为“setter”,当我们不通过它传递任何值时,它被称为“getter”。因为 Perl 将对象作为第一个参数传递,这意味着当它被称为“setter”时,我们实际上将获得 2 个参数,而当它被称为“getter”时,我们将获得一个参数。
“name”子例程中的第一条语句将参数分配给局部变量。现在在第二个语句中,Perl 检查函数应该充当 getter 还是充当 setter? Perl 检查参数的数量。如果它有两个参数,那么这是一个设置器。在这种情况下,它需要 $self 的内容。
如果我们使用 'name'函数作为 'getter',那么我们不会向它传递任何值,这意味着 $value 将是未定义的,但更重要的是@_将只有一个元素。这将跳过分配,它唯一要做的就是从哈希引用中返回“名称”键的值。
结论:
这表明 Perl 中对象的属性只是散列引用中的键/值对。
在上面的例子中,我们可以看到 setter/getter 只是一个普通的 Perl函数。
因此,它还实现了对象的属性是表示该对象的 HASH 引用中的简单条目。哈希中的键是属性的名称,哈希中的相应值是属性的值。