Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 为什么子类调用它的父类函数以及它们自己的函数?_Perl_Oop_Inheritance_Instantiation_Overriding - Fatal编程技术网

Perl 为什么子类调用它的父类函数以及它们自己的函数?

Perl 为什么子类调用它的父类函数以及它们自己的函数?,perl,oop,inheritance,instantiation,overriding,Perl,Oop,Inheritance,Instantiation,Overriding,我开始掌握Perl/Moose中继承的诀窍,但我开始遇到一些困难 例如,继承对象的构建顺序似乎是合理的,但继承似乎没有按照我的预期工作-- 如果我的基类调用BUILD,所有子类都将调用它们的BUILD以及基类的BUILD,但这并不限于moosey BUILD函数 如果我在基类中定义一个函数init(),并从基类构建中调用它,则会调用子类init(),而不是基类的init() 欧欧欧 为简洁起见,假设我们有以下对象构造: BaseClass ::BUILD --> call init

我开始掌握Perl/Moose中继承的诀窍,但我开始遇到一些困难

例如,继承对象的构建顺序似乎是合理的,但继承似乎没有按照我的预期工作--

如果我的基类调用BUILD,所有子类都将调用它们的BUILD以及基类的BUILD,但这并不限于moosey BUILD函数

如果我在基类中定义一个函数init(),并从基类构建中调用它,则会调用子类init(),而不是基类的init()

欧欧欧

为简洁起见,假设我们有以下对象构造:

BaseClass
    ::BUILD --> call init()
    ::init  --> do BaseStuff 

ChildClass extends BaseClass
    ::BUILD --> call init()
    ::init  --> do ChildStuff
现在实例化childClass

my $child = ChildClass->new();
根据调试输出,new()生成的调用顺序在我看来是这样的

BaseClass->BUILD()
BaseClass->init() <--- this calls ChildClass::init
ChildClass->BUILD()
ChildClass->init() <--- this calls ChildClass::init too!
然后

在这种情况下,哪一个是$class


别告诉我我必须重写BUILDARGS。。。哈哈

我假设每个类中都有一个类似的构建函数

sub BUILD {
    my $self = shift;
    ...
    $self->init();
    ...
}
Moose对待构建的方式与Perl通常对待方法调用的方式不同。当您在构建方法中调用init时,Perl将使用它的正常方法解析并查找子级的init方法,因为它屏蔽父级的init方法。然后,孩子的方法可以使用
$self->SUPER::init()
、Moose的“override”修饰符和
SUPER()
调用父母,而
SUPER:
只是使用
SUPER:
的修改方式

如果只在父类的BUILD方法中调用init,则可以使用任何标准的Moose方法修饰符(如“before”、“after”、“around”或“override”)来控制何时相对于父类的init调用子类的init

另一方面,如果希望在运行每个类的构建时调用该类的init,则可以明确要求Perl跳过标准方法查找,并使用指定类的方法:

package ParentClass;

sub BUILD {
    my $self = shift;
    ...
    $self->ParentClass::init();
    ...
}

package ChildClass;

sub BUILD {
    my $self = shift;
    ...
    $self->ChildClass::init();
    ...
}
sub BUILD {
    my $self = shift;
    ...
    $self->init();
    ...
}
package ParentClass;

sub BUILD {
    my $self = shift;
    ...
    $self->ParentClass::init();
    ...
}

package ChildClass;

sub BUILD {
    my $self = shift;
    ...
    $self->ChildClass::init();
    ...
}