7

我正在尝试实现一个 Moose::Role 类,它的行为类似于 Java 中的抽象类。我想在角色中实现一些方法,然后能够在具体类中覆盖这些方法。如果我使用与扩展类时相同的样式尝试此操作,则会出现错误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;

难道我做错了什么?我想要完成的事情应该以不同的方式完成吗?我想做的事根本不应该做吗?

4

2 回答 2

5

原来我使用不正确。我打开了一张票,并显示了这样做的正确方法:

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;

进行此更改具有预期的效果。

于 2013-10-08T12:53:20.243 回答
2

前段时间,我通过一个仅由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;

如果您只想为角色中定义的几个方法提供默认实现,请删除requiresfrom DefaultImpl

输出:

$ ./zpx.pl
这个
那
... 和另一个
于 2013-09-23T20:41:10.997 回答