为什么Perl的SUPER调用不使用箭头方法?

时间:2009-09-06 12:00:01

标签: perl oop

我注意到当你调用超类的方法时,你需要做这样的事情:

my $self = $class->SUPER::new();

为什么不是这样:

my $self = $class->SUPER->new();

4 个答案:

答案 0 :(得分:14)

我怀疑是因为$class->SUPER->new()通常与$class->SUPER()->new()相同。但是没有$class->SUPER()函数,并且不清楚会返回什么。

另一方面,$class->Foo::Bar一直是通过全名直接调用方法的有效方法,因此制作一个特殊的类似于包的东西 - SUPER - 更适合。 (我怀疑你实际上可以实现SUPER作为一个包,也许它在历史上是,我不知道)

PS:看一下mro包和$self->next::method。另外,如果您要在Perl中进行严肃的OO工作,请查看Moose。

答案 1 :(得分:13)

方法调用有多种形式:

调用方法,可能是继承的:

->method()

显式调用sub Package ::方法,无论是否在继承树中:

->Package::method()

显式调用引用的子,无论是否在继承树中:

->$coderef()

如果__PACKAGE__->method()中没有子方法,则调用__PACKAGE__调用的方法(注意->左侧的类或对象无关紧要):

->SUPER::method()

以上任何一项,取决于$method的内容:

->$method()

(即使在use strict;下也是合法的。)

虽然第一种形式是最常见的,但值得了解其他形式及其运作方式。

答案 2 :(得分:13)

简而言之,SUPER不是一种方法。这是一个虚拟包。它在{方法调用“部分的perlobj中记录。

但请注意,SUPER基于当前包,而不是您使用它的实例的包。

答案 3 :(得分:7)

添加到德罗伯特所说的内容:

你在'SUPER'命名空间中调用'new',但是传递对象(或字符串)'$ class'。

你没有拥有来使用SUPER,因为你可以提供父包的完整包名(在钻石继承的情况下很有用):

sub init {
   my $self = shift;
   $self->ParentClass1::init();
   $self->ParentClass2::init();
}