#!/usr/bin/perl
package child1;
use strict;
use warnings;
use Exporter;
use parent;
my @ISA=qw(cal Exporter);
sub new{
my $class=shift;
my $ref=cal->new();
bless ($ref,$class);
return $ref;
}
sub add{
my $ref=shift;
print "This is from child class";
my($a,$b)=@_;
return ($a+$b);
}
#的#parent.pm
#!/usr/bin/perl
package cal;
use strict;
use warnings;
use Exporter;
my @EXPORT=qw(add);
my @ISA=qw(Exporter EXPORT);
sub new{
my $class=shift;
my $ref=[];
bless ($ref,$class);
return $ref;
}
sub add{
my $ref=shift;
my $a=shift;
my $b=shift;
return ($a+$b);
}
1;
#!/usr/bin/perl
use strict;
use warnings;
use Exporter;
use child;
my @ISA=qw(child1 Exporter);
my $obj=new child1();
my $sum=$obj->add(1,2);
print "$sum=sum";
我收到错误无法在./test.pl第8行通过包“child1”找到对象方法“add”。 我想访问基类add方法 我收到上述错误
请澄清..
答案 0 :(得分:10)
这里的主要罪魁祸首是my @ISA
。要继承工作,您必须使用包@ISA
(使用our
声明它)。
但是,除此之外,您的代码中存在一些问题:
use parent 'cal'
而不是自己操纵@ISA
。Exporter
。new
,因为父级的new
是继承的。继承的new
是以一种已经支持继承的方式编写的。parent
模块已经存在,我在第一点使用它。答案 1 :(得分:6)
.pm模块不需要,也可能不需要#!/ usr / bin / perl行。这仅适用于要从命令行执行的程序,例如.pl模块。虽然你可以'perl -cw'你的.pm模块,或者用它们进行其他命令行调试,但这不是正常的“生产”使用。
.pl模块不应该包含@ISA或其他“我们的”声明,也不应该包含任何与导出器相关的内容。
如前所述,将“my”的包装内容改为“我们的”。 “我的”向外人隐瞒事情,好像这些陈述从未出现过。
在“cal”课程中,您想要以下内容吗?我赞成SUPER,因为它真实地展示了上发生的事情,并且更加通用。
package child1; use Exporter; our @ISA=qw(cal Exporter); sub new{ my $class=shift; my $ref=$class->SUPER::new(); return $ref; } }
最后一点:您可能需要在最终的打印声明中使用“\ n”。没有它,缓冲区在某些环境中可能无法在退出时正确刷新,因此您永远不会看到输出。
答案 2 :(得分:4)
@ISA
必须是公共包变量,而不是私有词法(my
)。 @EXPORT
也是如此。在所有这些声明中将my
更改为our
。
更好的是,根据您拥有的perl
版本,使用parent
或base
pragma简化您的生活,以加载超类并设置类关系。
关于样式,如果使包含模块代码的文件的路径与其包名匹配,则可以避免相当大的混淆。你应该注意perlmod documentation中描述的完善的惯例。
模块名称也大写,除非它们作为编译指示运行; pragma实际上是编译器指令,有时被称为“实用模块”(如果你是古典主义者,甚至称为“pragmata”)。
Cal模块使用perlobj documentation中描述的内部_initialize
方法来促进构造函数的继承。
请参阅下面的完整工作示例。
package Cal;
use strict;
use warnings;
sub new {
my $class=shift;
my $self=[];
bless ($self,$class);
$self->_initialize();
return $self;
}
sub _initialize {}
sub add {
my $ref=shift;
my $a=shift;
my $b=shift;
print "This is from parent class\n";
return ($a+$b);
}
1;
package Child1;
use warnings;
use strict;
use v5.10.1; # when parent was added to the core
use parent "Cal";
# if you have an older perl, use base instead of parent
# use base "Cal";
sub _initialize {
my $self=shift;
push @$self, "I am a " . ref($self) . "!";
}
sub add{
my $self=shift;
my($a,$b)=@_;
print "This is from child class\n";
return ($a+$b);
}
1;
#!/usr/bin/perl
use strict;
use warnings;
use Child1;
my $obj=Child1->new();
my $sum1=$obj->add(1,2);
print "$sum1=sum1\n";
# call the add method in Cal
my $sum2=$obj->Cal::add(1,2);
print "$sum2=sum2\n";
# call add as a class method of Cal, which
# happens to work in this case because Cal::add
# does not use the instance passed to it
my $sum3=Cal->add(1,2);
print "$sum3=sum3\n";
输出:
This is from child class 3=sum1 This is from parent class 3=sum2 This is from parent class 3=sum3