2

我有一个从超类调用方法的子类。超类中的方法使用在超类中定义为抽象(不是真正抽象)但在子类中实现的方法。

例如:

package BaseClass;

sub new
{

}
sub method1 {

    return someAbstractMethod();
}



sub someAbtsractMethod
{
     die "oops, this is an abstract method that should " . 
         "be implemented in a subclass" ;
}
1;

package SubClass;

sub new
{

}

sub someAbtsractMethod
{
     print "now we implement the asbtract method";
}
1;

现在当我这样做时:

$sub = new SubClass();
$sub->method1();

...它调用抽象消息,我得到指定的错误消息。如果我从超类中取出抽象方法并将实现留在子类中,它无法识别该方法并且我得到子例程抽象方法未找到错误。

4

4 回答 4

6

您尚未在父类和子类之间建立 IS_A 关系。

您可以base按照 Ivan 的建议使用 pragma 执行此操作,也可以操作@ISA数组。或者您可以使用parent编译指示。

@ISA:

package SubClass;
our @ISA = qw( BaseClass );

parent

package SubClass;
use parent qw( BaseClass );

顺便说一句,永远不要使用间接对象语法。要调用您的构造函数,请执行以下操作:

我的 $foo = SubClass->new();

此外,您似乎没有使用strictwarnings编译指示。这样做。总是。

最后,如果您在一个文件中有多个包,则将每个包包含在一个块中会很有帮助。

查看perlbootperltoot,它们是 perldoc 中方便的 OOP 教程。

更新:

我刚刚注意到您的方法调用已损坏。您需要在每个方法中找到调用类或实例。

package BaseClass;

sub new { bless {}, shift; }  # horrible constructor - do not reuse.

sub abstract { die "The present situation is abstract"; }

sub method { my $self = shift; $self->abstract; }


package SubClass;

our @ISA = qw( BaseClass );

sub abstract { print "It's alive\n" );

在脚本中:

my $obj = SubClass->new;
$obj->method;

my $base = BaseClass->new;
$base->method;

一定要阅读我链接到的教程。他们会帮助你。

于 2010-04-08T16:24:02.737 回答
3

您的根本问题是您根本没有使用方法调用。你做过吗

sub method1 {
  my $self = shift;
  $self->someAbstractMethod();
}

在基类中(并假设继承设置正确)然后事情会起作用。但是当你写someAbstractMethod()的不是方法调用,它是函数调用,所以它在编译时立即解析,而不考虑多态性(对象的类型是什么)。

于 2010-04-08T17:17:27.113 回答
3

你的代码有一些问题,你需要告诉子类它的父类是什么。您可能还需要设置构造函数以传递给父类。里面还有一些拼写错误。

package BaseClass;

sub new {
    bless {} => shift;
}
sub method1 {
    my $self = shift;

    return $self->someAbstractMethod();
}


sub someAbstractMethod
{
     die "oops, this is an abstract method that should " . 
         "be implemented in a subclass";
}


package SubClass;
use base 'BaseClass';

sub new {
    shift->SUPER::new
}

sub someAbstractMethod
{
     print "now we implement the asbtract method\n";
}


package main;

my $obj = BaseClass->new;

eval {$obj->method1(); 1} or warn $@;

my $subobj = SubClass->new;

$subobj->method1();
于 2010-04-08T16:28:48.547 回答
2

如果您刚开始使用 Perl OO,请不要忘记查看Moose。另请参阅Moose::Manual::Unsweetened以比较 Moose 与常规 Perl 5 OOP 样式。

于 2010-04-08T16:32:10.060 回答