我有一个名为 Foo::Base 的基类,我需要继承它的方法,比如“new”,并在一个范围内导入一些子例程名称:
package Foo::Base;
sub new { ... }
sub import {
no strict 'refs';
my $caller = caller;
*{"${caller}::my_sub"} = sub { 1 };
}
1;
所以,我需要在我的第二堂课 Foo::Child 中使用这个基类:
use base 'Foo::Base';
...并且它适用于继承,但它不会在范围内导入“my_sub”。我可以添加字符串
use Foo::Base;
对于它,它有帮助,但我不想写这样的东西:
use base 'Foo::Base';
use Foo::Base;
这看起来有点奇怪......这个问题有什么建议吗?
最佳答案
有两个原因可能想要做你正在做的事情,它们都是不好的。
首先是你试图从你的父类中导入方法......出于某种原因。也许你误解了 OO 的工作原理。你不需要这样做。只需将继承的方法称为方法,除非这些方法正在做一些古怪的事情,否则它将正常工作。
更有可能这是一个混合使用的模块,其中一些是方法,一些是导入的函数。为此,您可以...
use base 'Foo::Base';
use Foo::Base;
你正确地观察到它看起来有点奇怪......因为它有点奇怪。一个也导出的类是混合成语,这将导致奇怪的使用模式。
最好的办法是重新设计类而不是导出函数,或者将函数拆分到它们自己的模块中,或者使它们成为类方法。如果这些功能真的与类没有太大关系,那么最好将它们分离出来。如果它们确实与类有关,则将它们设为类方法。
use base 'Foo::Base';
Foo::Base->some_function_that_used_to_be_exported;
这消除了接口(interface)不匹配,并且作为奖励,子类可以像任何其他方法一样覆盖类方法行为。
package Bar;
use base 'Foo::Base';
# override
sub some_function_that_used_to_be_exported {
my($class, @args) = @_;
...do something extra maybe...
$class->SUPER::some_function_that_used_to_be_exported(@args);
...and maybe something else...
}
如果您无法控制基类,您仍然可以通过编写一个将导出的函数转换为方法的子类来使接口(interface)更加健全。
package SaneFoo;
use base 'Foo::Base';
# For each function exported by Foo::Base, create a wrapper class
# method which throws away the first argument (the class name) and
# calls the function.
for my $name (@Foo::Base::EXPORT, @Foo::Base::EXPORT_OK) {
my $function = Foo::Base->can($name);
*{$name} = sub {
my $class = shift;
return $function->(@_);
};
}
关于Perl:如何从基类导入子程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12978971/