如何调用祖父母的构造函数(因为未定义父的构造函数)?

时间:2016-07-31 18:33:02

标签: perl oop constructor super

我相信,通过这种方式来称呼家长的课程' Perl中的构造函数是:

package Child;
our @ISA = 'Parent';

sub new {
  my $class = shift;
  my @args = @_;
  my $self = $class->SUPER::new(@args);
  return $self;
}

但是,如果Parent没有明确定义new函数(但Grandparent确实存在),则此构造似乎不起作用。

就是这种情况,例如Net::FTP::File

tq84_ftp.pm

package tq84_ftp;

use warnings;
use strict;

our @ISA = qw(Net::FTP::File);

sub new {
  my $class = shift;
  my $self = $class->SUPER::new('localhost')
     or die($@);
  return $self;
}    

1;

script.pl

use tq84_ftp;
tq84_ftp->new();

输出:

Can't locate package Net::FTP::File for @tq84_ftp::ISA at tq84_ftp.pm line 10.
Can't locate package Net::FTP::File for @tq84_ftp::ISA at tq84_ftp.pm line 10.
Can't locate object method "new" via package "tq84_ftp" at tq84_ftp.pm line 10.

如何指定我希望Perl找到正确的(这里:grantparent' s)new函数?

2 个答案:

答案 0 :(得分:6)

  

但是,如果Parent没有明确定义新函数(但Grandparent确实存在),则此构造似乎不起作用。

不正确。

$ perl -E'
   package Grandparent {
      sub new { CORE::say(__PACKAGE__) }
   }

   package Parent {
      our @ISA = "Grandparent";
   }

   package Child {
      our @ISA = "Parent";
      sub new { my $class = shift; $class->SUPER::new(); }
   }

   Child->new();
'
Grandparent
  

Can't locate package Net::FTP::File

当您尝试从尚未声明的类继承时获得此警告。具体来说,您尝试使用Net :: FTP :: File而不加载它。

替换

our @ISA = 'Net::FTP::File';

use Net::FTP::File qw( );
our @ISA = 'Net::FTP::File';

use parent 'Net::FTP::File';
  

Can't locate object method "new" via package "tq84_ftp"

此消息有点不清楚,但是由于Net::FTP::File->new不存在这一事实。 Net :: FTP :: File不是一个类,更不用说Net :: FTP的子类了。它没有方法,更不用说new方法了。从Net :: FTP :: File继承是没有意义的。

您似乎想要创建Net :: FTP对象,因此请替换

use parent 'Net::FTP::File';

use parent 'Net::FTP';

最后,您要为Net :: FTP对象(包括从Net :: FTP继承的类的对象)添加的方法加载Net :: FTP :: File。为此,只需添加

即可
use Net::FTP::File qw( );

答案 1 :(得分:5)

您似乎认为Net::FTP::FileNet::FTP的子类,因此

my $self = $class->SUPER::new('localhost') ...

应该调用Net::FTP的{​​{1}}方法。

但实际上,new 不会 继承自Net::FTP::File。相反,它重新定义了Net::FTP中的一些方法。因此,如果您的类继承自Net::FTP,则它不会是Net::FTP::File的子级。

如果你看source code for Net::FTP,你可以很容易地看到这一点。请注意,下面没有Net::FTPuse base 'Net::FTP'use parent 'Net::FTP'

our @ISA = qw( Net::FTP )

等等。