【问题标题】:Method not found error when inheriting abstract method in Perl OOP在 Perl OOP 中继承抽象方法时找不到方法错误
【发布时间】:2010-04-08 16:10:00
【问题描述】:

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

例如:

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();

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

【问题讨论】:

    标签: perl oop inheritance abstract


    【解决方案1】:

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

    您可以按照 Ivan 的建议使用 base 杂注来执行此操作,或者您可以操作 @ISA 数组。或者你可以使用parent pragma。

    @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;
    

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

    【讨论】:

    • "顺便说一句,永远不要使用间接对象语法。"有人可以详细说明原因吗?
    • @MrD,主要问题是它不明确,很容易导致调用错误的函数/方法。见stackoverflow.com/questions/32955172/…
    【解决方案2】:

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

    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();
    

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 2013-11-28
          • 2013-07-01
          • 2012-11-17
          • 2021-08-14
          • 2014-07-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多