#!/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);
}
Run Code Online (Sandbox Code Playgroud)
##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;
Run Code Online (Sandbox Code Playgroud)
#!/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";
Run Code Online (Sandbox Code Playgroud)
我收到错误无法找到对象方法"添加"通过包"child1"在./test.pl第8行. 我想访问基类add方法,我得到上面的错误
请澄清..
amo*_*mon 10
这里的罪魁祸首是my @ISA.要继承工作,您必须使用包@ISA(声明它our).
但是,除此之外,您的代码中存在一些问题:
use parent 'cal'不要操纵@ISA自己.Exporter.new可以不reblessing写,因为父母的new继承.继承new是以已经支持继承的方式编写的.parent模块已经存在,我在第一点使用它.@ISA必须是公共包变量,而不是私有词法 ( my)。对于@EXPORT. 更改my为our所有这些声明。
更好的是,根据perl您拥有的版本,使用 theparent或basepragma 来简化您的生活,以加载超类并设置类关系。
关于样式,如果您使包含模块代码的文件的路径与其包名称相匹配,您将避免相当多的混淆。您最好注意perlmod 文档中描述的完善约定。
模块名称也大写,除非它们用作编译指示;pragma 实际上是编译器指令,有时称为“pragmatic modules”(如果您是古典主义者,甚至称为“pragmata”)。
Cal 模块使用perlobj 文档中_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;
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
#!/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";
Run Code Online (Sandbox Code Playgroud)
输出:
这是来自儿童班 3=和1 这是来自父类 3=和2 这是来自父类 3=和3
.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".没有它,缓冲区在某些环境中可能无法在退出时正确刷新,因此您永远不会看到输出.