2013-10-16 57 views
0

當調用Parent :: call_foo()時,我希望它總是調用Parent :: foo(),無論$ self是一個幸運的Parent還是一個有福的Child,並且不管Child是否超載foo() 。使用SUPER調用方法時,如何讓我的祝福散列(派生類)看起來像它的SUPER類?

此代碼打印:

parent foo 
parent call_foo, parent foo 
child foo 
child call_foo, parent call_foo, child foo 

但我想它打印:(最後一行父富)

parent foo 
parent call_foo, parent foo 
child foo 
child call_foo, parent call_foo, parent foo 

-

use Parent; 
use Child; 

my $par = Parent->new(); 
my $chd = Child->new(); 

$par->foo(); 
$par->call_foo(); 

$chd->foo(); 
$chd->call_foo(); 

-

package Parent; 

sub new { 
    my $class = shift; 
    return bless({}, $class); 
} 

sub foo { 
    print "parent foo\n"; 
} 

sub call_foo { 
    my $self = shift; 
    print "parent call_foo, "; 
    $self->foo(); 
} 
1; 

-

package Child; 
use base qw(Parent); 

sub foo { 
    print "child foo\n"; 
} 

sub call_foo { 
    my $self = shift; 
    print "child call_foo, "; 
    $self->SUPER::call_foo(); 
} 
1; 

回答

1

在家長call_foo,只需調用foo作爲一個子程序,而不是一個方法。這將始終調用父版本。您可以使用$self->Parent::foo()而不是foo($self)。區別在於$self->Parent::foo()執行正常的方法查找,但是從父類開始(即,如果父實際從基類繼承其foo方法,它將起作用)。既然您知道foo存在於Parent類中,您可以通過直接調用它來節省方法查找的開銷。

+0

方法查找只進行一次 - 結果被緩存 - 所以避免了'$ self-> Parent :: foo()'實際上並沒有保存任何東西。也就是說,我不喜歡硬編碼當前的包名,所以我可能會使用'foo($ self)'。 – ikegami

+0

我很好奇,爲什麼我不能使用'__PACKAGE __ :: foo()'而不是硬編碼?我可以看到它不能編譯,但我不明白爲什麼這是不允許的。無論哪種方式,我想我會''self-> Parent :: foo()',因爲在這段代碼中的一些情況下,似乎孩子正在重載一個「祖父母」方法,但父母必須始終調用祖父母版本。 –

+0

'__PACKAGE __-> foo($ self);'似乎是允許Parent從基類繼承foo,並且永遠不會調用子版本的最佳解決方案,所有這些都沒有在軟件包名稱中進行硬編碼。 –

相關問題