很抱歉非常模糊,但我不知道这个概念的名称。我会尽力解释。我会试着把它放在动物身上以使其变得容易。
我有一个通用的超类。这个超类包含所有动物必须做的功能。例如,我不想在每个动物子类中重新定义“take_breath”子,因此我在动物超类中定义它一次,并且所有动物(动物::猫,动物::狗和动物:: Llama)可以简单地访问$ self-> take_breath()。这些动物也经历了许多相同的初始化程序,而不是每次我只是简单地调用$ class-> SUPER :: new(@_)以及做那些动物特有的事情时重新定义它们。
每当初始化动物时,都会说这是超级类的初始化程序。有数百种动物,它们运行数百次。这不是一个大问题。
这些动物很聪明,但知道如何使用LWP :: UserAgent网络浏览器。要访问互联网,他们必须登录网页并设置会话cookie。它们共享相同的登录名,并希望共享相同的浏览器。在我当前的实现中,登录例程是超类的新方法的一部分。这意味着当一只动物被初始化时,它会运行并且动物会登录。正如我所说,我有数百只动物并且不想发动数百次POST请求。我想以某种方式启动登录例程一次,使其成为超级类的一部分。然后,每只动物都可以通过$ self-> {'ua'}访问“共享”网络浏览器。
我希望这可以解释它,我不确定这个OOP术语是什么。
TLDR适用于那些不喜欢动物的人
我在超类中有一个登录例程,它创建一个LWP :: UserAgent,登录并设置会话cookie。子类都可以共享一个登录名。我不想为每个子类发起数百个POST请求。我想以某种方式登录一次并与所有子类共享准备好的$ ua对象。
答案 0 :(得分:2)
有两种方法可以解决这个问题:
并非每个动物实例都有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();
...
}
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单例构造函数。