创建了一个Perl模块:
use ElectricCommander;
use strict;
use warnings;
package EC;
sub new
{
my $class = shift;
my $server = shift;
my $self = {};
bless( $self, $class );
$self->{EC} = ElectricCommander->new($server);
$self->{EC}->login("user", "password");
return $self;
}
1;
在脚本中,有没有办法调用ElectricCommander模块中的方法? 例如,电子控制器中存在getJobStatus,我可以执行下面的操作吗?
use EC;
$obj = EC->new("myserver");
$obj->getJobDetails("1234");
答案 0 :(得分:1)
只需将以下内容添加到EC
包中:
sub getJobDetails { shift->{EC}->getJobDetails(@_) }
如果您有多种类型的方法,则可以使用动态构建包装器。
BEGIN {
for my $method_name (qw( getJobDetails ... )) {
my $local_method = sub { shift->{EC}->$method_name(@_) };
no strict qw( refs );
*$method_name = $local_method;
}
}
您甚至可以将所有来电重定向到EC
中不存在的方法,如下所示:
use Carp qw( croak );
sub AUTOLOAD {
my $method_name = our $AUTOLOAD;
$method_name =~ s/^.*:://s;
return if $method_name eq 'DESTROY';
my $remote_method = $_[0]->can($method_name)
or croak(sprintf("Can't locate object method \"%s\" via package \"%s\"", $method_name, ref($_[0])));
my $local_method = sub { shift->{EC}->$remote_method(@_) };
no strict qw( refs );
*$method_name = $local_method;
goto &$method_name;
}
答案 1 :(得分:1)
这里的组合似乎很合适:将方法添加到EC
以分派给其他类的方法。
例如
package EC;
use strict;
use warnings;
use ElectricCommander;
sub new {
...
$self->{EC} = ElectricCommander->new($server);
...
}
sub getJobDetails {
my ($self, @args) = @_;
$self->{EC}->getJobDetails(@args);
}
你可以致电
use EC;
my $ec_obj = EC->new(...);
$ec_obj->getJobDetails(...);
您还可以将ElectricCommander
实例化为class data,而不是new
,以便EC
为use
时,其对象构建一次。这是一个设计选择,无论您是希望EC
个实例都有自己的ElectricCommander
对象,根据需要构建,或者一个对象是否符合所有EC
对象的需求。
如果EC
要真正扩展ElectricCommander
- 要使用它的大多数方法,重写一些并添加更多 - 那么你可以让它继承自ElectricCommander
的<子类。 / p>
大多数情况下,你需要在另一个你想要的合成中使用一个类,如上所示,一个类使用另一个类的功能( has-a relationship )。当您构建一个经过深思熟虑的类层次结构时,继承是合适的,其中父级放置更多的一般或抽象行为,而其子类主要专门化它(是一种关系)。
答案 2 :(得分:1)
ElectricCommander
实例可以使用EC
的所有方法的最简单方法是将EC
作为ElectricCommander
的子类:
package EC;
use strict;
use warnings;
use parent 'ElectricCommander';
sub new
{
my $class = shift;
my $self = $class->SUPER::new(@_);
$self->login("user", "password");
return $self;
}
1;
现在
use EC;
my $obj = EC->new("myserver");
$obj->getJobDetails("1234");
应该工作(tm)。