如何在Perl中调用基类中的方法

sauutmhj  于 2023-08-06  发布在  Perl
关注(0)|答案(3)|浏览(162)

#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方法,我得到上面的错误

请澄清…

0yg35tkg

0yg35tkg1#

这里的罪魁祸首是my @ISA。要使继承工作,必须使用@ISA包(用our声明)。
然而,在你的代码中还有一些问题:
1.请使用use parent 'cal',而不是自己操作@ISA
1.面向对象的模块几乎没有理由使用Exporter
1.可以写入child1的new而无需重新祝福,因为父代的new是继承的。继承的new以已经支持继承的方式编写。
1.不要给你的模块起小写的名字,这些是为“pragmas”保留的。parent模块已经存在,我在第一点中使用了它。

zvokhttg

zvokhttg2#

@ISA必须是一个公共包变量,而不是私有词法(my)。@EXPORT也是如此。在所有这些声明中将my更改为our
更好的是,根据您拥有的perl版本,使用parentbase杂注来加载超类并设置类关系,从而简化您的工作。
在样式方面,如果使包含模块代码的文件的路径与它们的包名相匹配,则可以避免相当大的混乱。您最好注意perlmod文档中描述的一个完善的约定。
模块名也是大写的,除非它们用作杂注; pragma实际上是编译器指令,有时被称为“pragmatic modules”(如果你是一个古典主义者,甚至可以称为“pragmata”)。
Cal模块使用perlobj文档中描述的内部_initialize方法来促进构造函数的继承。
下面是一个完整的工作示例。

Cal.pm

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;

字符串

Child1.pm

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;

test.pl

#!/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

hrysbysz

hrysbysz3#

.pm模块不需要,也可能不想要#!/usr/bin/perl行。这仅适用于从命令行执行的程序,如.pl模块。虽然您可以'perl-cw'您的.pm模块,或使用它们进行其他命令行调试,但这不是正常的“生产”使用。
并且.pl模块不应该有@伊萨,或者在包中发现的其他“我们的”声明,也不应该有任何与导出器相关的东西。
如前所述,将包内容的“my”改为“our”。“我的”对外人隐藏了一些东西,好像这些陈述从来没有出现过。
在“cal”类中,你想要像下面这样的东西吗?我喜欢SUPER,因为它真正显示了and is much more generic上发生的事情。

package child1;
use Exporter;
our @ISA=qw(cal Exporter);

sub new{
        my $class=shift;
        my $ref=<b>$class-&gt;SUPER::new()</b>;
        return $ref;
        }

字符串
最后一点:你可能需要在最后的print语句中加上“\n”。如果没有它,在某些环境中,缓冲区可能无法在退出时正确刷新,因此您将永远看不到输出。

相关问题