Как вызвать метод в базовом классе в Perl
#ребенок.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);
}
##родитель.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";
Я получаю ошибку, не могу найти метод объекта "добавить" через пакет "child1" at ./test.pl строка 8. Я хочу получить доступ к методу add базового класса и я получаю это выше ошибки
просьба уточнить..
3 ответов
The .модули pm не нужны и, скорее всего, не хотят,#!/usr/bin / perl lines. Это только для программ, предназначенных для выполнения из командной строки, как ваш .модуль pl. В то время как вы можете "perl-cw" ваш .модули pm или другая отладка командной строки с ними, это не обычное" производственное " использование.
и .модули pl не должны иметь @ISA или другие" наши " декларации, найденные в пакетах, или любые связанные с экспортером вещи.
Как уже было сказано, измените " my " на упакуйте вещи в "наши". "Мое" скрывает вещи для посторонних, как будто заявлений никогда не было.
в классе " cal " вы хотите что-то вроде следующего? Я предпочитаю супер, как это действительно показывает, что происходит и гораздо более общие.
package child1; use Exporter; our @ISA=qw(cal Exporter); sub new{ my $class=shift; my $ref=$class->SUPER::new(); return $ref; } }
один заключительный момент: вам может понадобиться "\n" в окончательном операторе печати. Без него буфер может не сбросить правильно при выходе в некоторых средах, поэтому вы никогда не увидите вывод.
главным виновником здесь является my @ISA
. Чтобы наследование работало, вы должны использовать пакет @ISA
(объявим его с our
).
однако в вашем коде есть некоторые проблемы помимо этого:
- пожалуйста
use parent 'cal'
вместо манипулирования@ISA
себя. - объектно-ориентированные модули имеют мало оснований для использования
Exporter
. - пакета child1 это
new
может быть написана без reblessing, потому что родителейnew
передается по наследству. Унаследованноеnew
написано таким образом, что уже поддерживает наследование. - не давайте своим модулям строчные имена, они зарезервированы для"прагм". The
parent
модуль уже существует, и я использовал его в моем 1-ом пункте.
@ISA
должна быть переменная открытого пакета, а не частная лексическая (my
). Же для @EXPORT
. Изменить my
to our
на все эти заявления.
еще лучше, в зависимости от версии perl
у вас есть, упростить вам жизнь с parent
или base
pragma для загрузки суперклассов и настройки отношений классов.
что касается стиля, вы избежите значительной путаницы, если сделаете пути к файлам, содержащим код ваших модулей, соответствуют их именам пакетов. Вам следует прислушаться к устоявшемуся соглашению, описанному в документация perlmod.
имена модулей также капитализируются, если они не функционируют как прагмы; прагмы фактически являются директивами компилятора и иногда называются " прагматическими модулями "(или даже" прагматами", если вы классик).
модуль Cal использует внутреннее _initialize
метод, как описано в perlobj документация для облегчения наследования конструктора.
см. ниже полный рабочий пример.
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, так.ПМ
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