sli*_*oad 0 oop polymorphism perl
在Perl中似乎有很多方法可以做多态,但他们都对我感到"hacky".我对Perl有点新意,所以我可能只是错误地解释它,但我发现大多数例子都会使你的代码难以辨认并且引起争议.
假设您有一个窗口小部件类,其中包含所有窗口小部件所需的一些数据和方法.还有一些小部件类型(即日历,日程安排等).并且他们需要彼此通信(通过父容器类).
使用命名空间并使小部件成为原型值得吗?
我应该在实例化时为每个窗口小部件提供对象(其中一种类型)的引用吗?
只是忘记作为对象的类型,并使widget成为一个大类,其中每个实例只根据设置的类型使用几个方法.别的什么?
我来自C/C++背景,我发现很难决定Perl编程模型.
此外,我没有强大的类型安全或私人成员要求.该项目是一个中等规模的Web应用程序,有几个开发人员和其他项目的可移植性不是一个优先事项.尽管如此,易于扩展而无需破译Perl黑客将是有用的.
"现代Perl"方法可能被定义Widget为一个角色.可以认为角色类似于mixin,接口或抽象基类.使用Moose :: Role或其中一个更轻量级的替代品(Moo :: Role,Role :: Tiny)来做这件事.
{
package Widget;
use Moo::Role;
sub some_common_method {
my $self = shift;
...;
}
sub another_common_method {
my $self = shift;
...;
}
# Here we're indicating that all Widgets must
# have a method called yet_another_common_method,
# but we're not defining how that method should
# be implemented.
requires "yet_another_common_method";
}
Run Code Online (Sandbox Code Playgroud)
现在您可以创建一个组成该角色的类:
{
package Calendar;
use Moo;
with "Widget";
# Here's a member variable.
has year => (is => "ro", required => 1);
# Widget requires us to implement this.
sub yet_another_common_method {
my $self = shift;
...;
}
# We can override Widget's implementation
# of this method.
sub some_common_method {
my $self = shift;
...;
}
# We can install hooks ("method modifiers")
# to Widget's methods.
before another_common_method => sub {
my $self = shift;
print STDERR "Calendar ", $self->year, ": another_common_method() was called.\n";
};
}
Run Code Online (Sandbox Code Playgroud)
而另一个:
{
package Schedule;
use Moo;
with "Widget", "Editable";
sub yet_another_common_method {
my $self = shift;
...;
}
}
Run Code Online (Sandbox Code Playgroud)
并使用类:
my $calendar = Calendar->new( year => 2014 );
my $schedule = Schedule->new;
my @widgets = ($calendar, $schedule);
for (@widgets) {
$_->some_common_method if $_->does('Widget');
}
Run Code Online (Sandbox Code Playgroud)