#child.pm
#!/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;
型
#test.pl
#!/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";
型
**我得到错误Can 't locate object method“add”via package“child 1”at ./test.pl line 8.**我想访问基类add方法,我得到上面的错误
请澄清…
3条答案
按热度按时间0yg35tkg1#
这里的罪魁祸首是
my @ISA
。要使继承工作,必须使用@ISA
包(用our
声明)。然而,在你的代码中还有一些问题:
1.请使用
use parent 'cal'
,而不是自己操作@ISA
。1.面向对象的模块几乎没有理由使用
Exporter
。1.可以写入child1的
new
而无需重新祝福,因为父代的new
是继承的。继承的new
以已经支持继承的方式编写。1.不要给你的模块起小写的名字,这些是为“pragmas”保留的。
parent
模块已经存在,我在第一点中使用了它。zvokhttg2#
@ISA
必须是一个公共包变量,而不是私有词法(my
)。@EXPORT
也是如此。在所有这些声明中将my
更改为our
。更好的是,根据您拥有的
perl
版本,使用parent
或base
杂注来加载超类并设置类关系,从而简化您的工作。在样式方面,如果使包含模块代码的文件的路径与它们的包名相匹配,则可以避免相当大的混乱。您最好注意perlmod文档中描述的一个完善的约定。
模块名也是大写的,除非它们用作杂注; pragma实际上是编译器指令,有时被称为“pragmatic modules”(如果你是一个古典主义者,甚至可以称为“pragmata”)。
Cal模块使用perlobj文档中描述的内部
_initialize
方法来促进构造函数的继承。下面是一个完整的工作示例。
Cal.pm
字符串
Child1.pm
型
test.pl
型
输出量:
型
hrysbysz3#
.pm模块不需要,也可能不想要#!/usr/bin/perl行。这仅适用于从命令行执行的程序,如.pl模块。虽然您可以'perl-cw'您的.pm模块,或使用它们进行其他命令行调试,但这不是正常的“生产”使用。
并且.pl模块不应该有@伊萨,或者在包中发现的其他“我们的”声明,也不应该有任何与导出器相关的东西。
如前所述,将包内容的“my”改为“our”。“我的”对外人隐藏了一些东西,好像这些陈述从来没有出现过。
在“cal”类中,你想要像下面这样的东西吗?我喜欢SUPER,因为它真正显示了
and is much more generic
上发生的事情。字符串
最后一点:你可能需要在最后的print语句中加上“\n”。如果没有它,在某些环境中,缓冲区可能无法在退出时正确刷新,因此您将永远看不到输出。