Perl-如何在子类中创建方法别名?
我试图在子类中创建一个超级类泛型方法的别名,但它似乎不起作用。这个技巧在同一个类中有效,但在超级/子转换中似乎不起作用。下面是一个真实的基本示例。前两个电话有效。第三个调用生成关于未定义子例程的错误。我也尝试过使用SUPER::cat,但也不起作用Perl-如何在子类中创建方法别名?,perl,class,Perl,Class,我试图在子类中创建一个超级类泛型方法的别名,但它似乎不起作用。这个技巧在同一个类中有效,但在超级/子转换中似乎不起作用。下面是一个真实的基本示例。前两个电话有效。第三个调用生成关于未定义子例程的错误。我也尝试过使用SUPER::cat,但也不起作用 package foo; sub cat{ print("inside foo\n"); } *bird = \&cat; package bar; use base 'foo'; *dog = \&cat; pack
package foo;
sub cat{
print("inside foo\n");
}
*bird = \&cat;
package bar;
use base 'foo';
*dog = \&cat;
package main;
foo::cat();
foo::bird();
bar::dog();
这:
应该是:
*dog = \&foo::cat;
您混淆了面向对象继承和简单符号导入 正如您所说的,
使用基'foo'
声明了一个超类。这意味着将检查foo
中是否存在对bar
中未显示的方法的调用
但是,*dog=\&cat
不是一个方法调用:它只是一个全局赋值,因此搜索不会超出&bar::cat
如果您编写的是真正面向对象的代码,那么像这样分配给*bar::dog
将破坏继承机制的作用
要观察Perl的面向对象功能,请将glob赋值移动到foo
(这里它只是给一个方法添加别名),并使用方法调用语法进行调用
在这段代码中,bar
没有自己的方法,它继承了foo
的所有内容,但代码仍按预期工作
package foo;
sub cat {
print("inside foo\n");
}
*bird = \&cat;
*dog = \&cat;
package bar;
use base 'foo';
package main;
bar->cat();
bar->bird();
bar->dog();
输出
inside foo
inside foo
inside foo
你应该写
sub dog { shift->cat(@_) }
(基本上是转换
cat
方法)而不是使用glob赋值,这样bar
的子类可以覆盖或扩展cat
,而不会破坏bar
的契约,即cat
和dog
做同样的事情。将Borodin的思想进一步介绍,假设您正在执行正确的OO,但确实希望父类提供的方法有一个别名,并且只在这个子类(以及更深层的子类)中。在这种情况下,您可能需要:
#!/usr/bin/env perl
package foo;
sub new { return bless {}, shift }
sub cat{
print("inside foo\n");
}
*bird = \&cat;
package bar;
use base 'foo';
sub dog { $_[0]->can('cat')->(@_) }
package main;
my $bar = bar->new;
$bar->cat();
$bar->bird();
$bar->dog();
此机制在堆栈跟踪中保留
dog
。如果您不想这样做,您可以使用goto&sub
表单,但由于您只有在知道原因的情况下才应该这样做,因此我不打算在这里举一个例子。这确实有效。我只是不清楚我为什么需要它。“use base”不应该将所有父方法导入我的子类吗?“use base”与基类+1建立ISA关系:我的评论变成了自己的答案:
#!/usr/bin/env perl
package foo;
sub new { return bless {}, shift }
sub cat{
print("inside foo\n");
}
*bird = \&cat;
package bar;
use base 'foo';
sub dog { $_[0]->can('cat')->(@_) }
package main;
my $bar = bar->new;
$bar->cat();
$bar->bird();
$bar->dog();