我正在尝试实现一个Moose :: Role类,其行为类似于Java中的抽象类。我想在Role中实现一些方法,但是能够在具体类中覆盖这些方法。如果我使用与扩展类时相同的样式尝试此操作,则会收到错误Cannot add an override method if a local method is already present
。这是一个例子:
我的抽象类:
package AbstractClass;
use Moose::Role;
sub my_ac_sub {
my $self = shift;
print "In AbstractClass!\n";
return;
}
1;
我的具体课程:
package Class;
use Moose;
with 'AbstractClass';
override 'my_ac_sub' => sub {
my $self = shift;
super;
print "In Class!\n";
return;
};
__PACKAGE__->meta->make_immutable;
1;
然后:
use Class;
my $class = Class->new;
$class->my_ac_sub;
我做错了吗?我想要完成的是应该以不同的方式完成的吗?是不是我不想做的事情?
答案 0 :(得分:4)
原来我错误地使用了它。我打开a ticket并显示了正确的方法:
package Class;
use Moose;
with 'AbstractClass';
around 'my_ac_sub' => sub {
my $next = shift;
my $self = shift;
$self->$next();
print "In Class!\n";
return;
};
__PACKAGE__->meta->make_immutable;
1;
进行此更改会产生预期的效果。
答案 1 :(得分:2)
Some time ago,我通过一个仅由requires
语句组成的角色来做到这一点。这形成了抽象基类。然后,您可以将默认实现放在另一个类中并继承自:
#!/usr/bin/env perl
use 5.014;
package AbstractClass;
use Moose::Role;
requires 'my_virtual_method_this';
requires 'my_virtual_method_that';
package DefaultImpl;
use Moose;
with 'AbstractClass';
sub my_virtual_method_this {
say 'this';
}
sub my_virtual_method_that {
say 'that'
}
package MyImpl;
use Moose;
extends 'DefaultImpl';
with 'AbstractClass';
override my_virtual_method_that => sub {
super;
say '... and the other';
};
package main;
my $x = MyImpl->new;
$x->my_virtual_method_this;
$x->my_virtual_method_that;
如果您只想为角色中定义的几种方法提供默认实施,请从requires
移除DefaultImpl
。
输出:
$ ./zpx.pl this that ... and the other