Perl OOP 中继承抽象方法时,找不到方法错误

发布于 2024-08-28 07:46:29 字数 605 浏览 7 评论 0原文

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

例如:

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

...它调用抽象消息,并且我收到指定的错误消息。如果我从超类中去掉抽象方法,而只将实现留在子类中,它不会识别该方法,并且会出现“子例程抽象方法未找到”错误。

I have a subclass that calls a method from a superclass. The method in the superclass uses a method that is defined in the superclass as abstract (not really abstract) but implemented in the subclass.

For example:

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;

Now when I do:

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

...it calls the abstract message and I get the specified error message. If I took off the abstract method from the super class and just leave the implementation in the subclass, It does not recognize the method and I get subroutine abstract method not found error.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

旧人九事 2024-09-04 07:46:29

您尚未在父类和子类之间设置 IS_A 关系。

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

@ISA:

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

parent

package SubClass;
use parent qw( BaseClass );

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

my $foo = SubClass->new();

另外,您似乎没有使用 strict警告 编译指示。这样做。总是。

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

查看 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;

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

You haven't set up an IS_A relationship between the parent and child classes.

You can do this with the base pragma as Ivan suggests, or you can manipulate the @ISA array. Or you can use the parent pragma.

@ISA:

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

parent:

package SubClass;
use parent qw( BaseClass );

By the way, don't use the indirect object syntax ever. To call your constructor do:

my $foo = SubClass->new();

Also, it looks like you aren't using the strict and warnings pragmas. Do so. Always.

Finally, if you have multiple packages in one file, it is helpful to enclose each package in a block.

Check out perlboot and perltoot, they are handy OOP tutorials in the perldoc.

Update:

I just noticed that your method calls are broken. You need to find the invoking class or instance in each method.

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

In the script:

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

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

Definitely read the tutorials I linked to. They will help you.

止于盛夏 2024-09-04 07:46:29

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

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

There are some problems with your code, you need to tell the subclass what its parent class is. You also probably need to setup your constructors to pass through to the parent class. There were also a few misspellings in there.

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();
听,心雨的声音 2024-09-04 07:46:29

您的根本问题是您根本没有使用方法调用。如果您

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

在基类中完成了操作(并且假设继承设置正确),那么一切都会正常。但是,当您编写 someAbstractMethod() 时,它不是方法调用,而是函数调用,因此它会在编译时立即解析,而不考虑多态性(对象的类型是什么)。

Your fundamental problem is that you're not using method calls at all. Had you done

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

in the base class (and assuming inheritance was set up properly) then things would work. But when you write someAbstractMethod() that's not a method call, it's a function call, so it's resolved immediately at compile-time, without any regard for polymorphism (what the type of the object is).

脸赞 2024-09-04 07:46:29

如果您刚刚开始使用 Perl OO,请不要忘记查看 Moose。另请参阅 Moose::Manual::Unsweetened 了解 Moose 的比较具有常规 Perl 5 OOP 风格。

If you are just starting out with Perl OO dont forget to check out Moose. See also Moose::Manual::Unsweetened for a comparison of Moose with regular Perl 5 OOP style.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文