为什么$ class-> SUPER :: new在使用多重继承时不调用所有父类的构造函数?

Ome*_*evy 4 perl multiple-inheritance

我试图在Perl中使用多继承,但我无法弄清楚如何从子构造函数调用多个父构造函数.

A.pm:

package A;
use Carp qw (croak);
use strict;
use warnings;

sub new {
    my $class = shift;
    print "This is A new\n";
    my $self->{DEV_TYPE} = shift || "A";
    bless($self, $class);
    return $self;
}

sub a_func{
    print "This is A func\n";
}

1;
Run Code Online (Sandbox Code Playgroud)

B.pm:

package B;
use Carp qw (croak);
use strict;
use warnings;

sub new {
    my $class = shift;
    print "This is B new\n";
    my $self->{DEV_TYPE} = shift || "B";
    bless($self, $class);
    return $self;
}

sub b_func{
    print "This is B func\n";
}

1;
Run Code Online (Sandbox Code Playgroud)

C.pm:

package C;
use Carp qw (croak);
use strict;
use warnings;
eval "use A";
die $@ if $@;
eval "use B";
die $@ if $@;
our @ISA = ("A","B");

sub new {
    my $class = shift;
    my $self = $class->SUPER::new(@_);
    print "This is C new\n";
    $self->{DEV_TYPE} = shift || "C";
    bless($self, $class);
    return $self;
}

sub c_func{
    print "This is C func\n";
}

1;
Run Code Online (Sandbox Code Playgroud)

C::new,$class->SUPER::new不调用B的构造函数.如果我明确地调用它$class->B::new(@_);,我得到错误

无法通过包"B"在C.pm找到对象方法"new"

我究竟做错了什么?

Thi*_*Not 7

$class->SUPER::new总是打电话,A::new因为A来自B in @ISA.请参阅perlobj中的方法解析顺序:

当一个类有多个父项时,方法查找顺序变得更加复杂.

默认情况下,Perl对方法进行深度优先从左到右的搜索.这意味着它从@ISA数组中的第一个父项开始,然后搜索它的所有父项,祖父母等.如果找不到该方法,它将转到原始类的@ISA数组中的下一个父项并从那里搜索.

这意味着$class->SUPER::new只会调用其中一个父构造函数.如果您有需要从孩子同时运行父类的初始化逻辑,如在其移动到不同的方法这篇文章.


当你明确地打电话B::new$class->B::new,你会得到

无法通过包"B"在C.pm找到对象方法"new"

因为use B正在加载核心模块B而不是你的模块.您应该重命名您的模块.


请注意,最好使用parentpragma而不是@ISA手动设置,例如

use parent qw(Parent1 Parent2);
Run Code Online (Sandbox Code Playgroud)

parent负责加载父模块,因此你可以删除相关的use语句(eval顺便说一句,你不应该这样做).