Perl可以处理这个OOP概念 - 在动物术语中解释

时间:2013-06-21 17:09:30

标签: perl class oop subclass superclass

很抱歉非常模糊,但我不知道这个概念的名称。我会尽力解释。我会试着把它放在动物身上以使其变得容易。

我有一个通用的超类。这个超类包含所有动物必须做的功能。例如,我不想在每个动物子类中重新定义“take_breath”子,因此我在动物超类中定义它一次,并且所有动物(动物::猫,动物::狗和动物:: Llama)可以简单地访问$ self-> take_breath()。这些动物也经历了许多相同的初始化程序,而不是每次我只是简单地调用$ class-> SUPER :: new(@_)以及做那些动物特有的事情时重新定义它们。

每当初始化动物时,都会说这是超级类的初始化程序。有数百种动物,它们运行数百次。这不是一个大问题。

这些动物很聪明,但知道如何使用LWP :: UserAgent网络浏览器。要访问互联网,他们必须登录网页并设置会话cookie。它们共享相同的登录名,并希望共享相同的浏览器。在我当前的实现中,登录例程是超类的新方法的一部分。这意味着当一只动物被初始化时,它会运行并且动物会登录。正如我所说,我有数百只动物并且不想发动数百次POST请求。我想以某种方式启动登录例程一次,使其成为超级类的一部分。然后,每只动物都可以通过$ self-> {'ua'}访问“共享”网络浏览器。

我希望这可以解释它,我不确定这个OOP术语是什么。

TLDR适用于那些不喜欢动物的人

我在超类中有一个登录例程,它创建一个LWP :: UserAgent,登录并设置会话cookie。子类都可以共享一个登录名。我不想为每个子类发起数百个POST请求。我想以某种方式登录一次并与所有子类共享准备好的$ ua对象。

1 个答案:

答案 0 :(得分:2)

有两种方法可以解决这个问题:

1。包变量

并非每个动物实例都有UA,但UA是动物的一部分。您可以在启动时初始化UA。动物可以通过访问者或变量访问UA:

package Animal;

my $ua = LWP::UserAgent->new();

sub ua { $ua }

然后

my $ua = $self->ua();

package Animal;

our $ua = LWP::UserAgent->new();

然后

my $ua = $Animal::ua;

技术术语是类变量,或者是Java 静态方法静态变量等语言。

Java翻译:

class Animal {
  private static LWP.UserAgent ua = new LWP.UserAgent();
  public static LWP.UserAgent getUa() { return ua }
  ...
}

class Animal {
  public static LWP.UserAgent ua = new LWP.UserAgent();
  ...
}

2。 state变量

在较新的Perls(> = v5.10?)中,您可以使用state声明变量。他们宣布了词汇变量。变量在程序的生命周期内初始化一次,而不是每次执行语句时(与my一样)。

use feature 'state';
package Animal;
sub new {
  my ($class, %args) = @_;
  state $ua = LWP::UserAgent->new;
  bless { ua => $ua, %args } => $class;
}

然后

my $ua = $self->{ua};

使用do块来执行更广泛的初始化

可能很有用
state $ua = do {
  my $ua = LWP::UserAgent->new;
  ...;
  $ua;
};

或将初始化卸载到子:state $ua = make_ua();

如果你必须定位早期的perls,你可以将new子包含在一个单独的范围内,并将那里的变量声明为类似效果的词汇:

package Animal;

{
  my $ua = LWP::UserAgent->new;
  sub new {
    my ($class, %args) = @_;
    bless { ua => $ua, %args } => $class;
  }
}

这里唯一的区别是初始化UA时。 (当然,还有刺激性括号的数量。)正如Len Jaffe所述,可以对初始化进行修改:

package Animal;

{
  my $ua; # just declare scope here
  sub new {
    my ($class, %args) = @_;
    $ua ||= LWP::UserAgent->new;  # $ua is false until initialized
    bless { ua => $ua, %args } => $class;
  }
}

因为对象是引用,所有动物都将获得相同的UA。

特别是在C / C ++中,这也称为静态变量state修饰符可以被视为非OO单例构造函数。