views:

196

answers:

5

Hello,

I have a sub class that calls a method from a super class. and the method in the super class use a method that is defined in the super class as asbstract(not really abstract) but implemented in the sub class.

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 abstractmethod from the super class and just leave the implementation in the subclass, It does not recognize the method and I get subroutine abstractmethod not found error.

+2  A: 

Inheritance doesn't work that way. A superclass is not aware of its subclasses. You'll should override method1() in the subclass if you want it to call its version of someAbstractMethod(). That said, if it's really a method (and not a subroutine) you should be calling it via dispatch syntax:

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

which will (assuming $self has been blessed into the subclass) call the right version of someAbstractMethod(). This has a bad code smell about it, though. Why do you have a concrete superclass method calling an abstract one?

Michael Carman
There's no need at all to override method1 in the subclasses; just having a proper definition of method1 in the superclass will work fine. And there's nothing bad about doing it; it's an easy way to do a form of IoC.
hobbs
This answer is wrong. Inheritance does work that way and calling abstract methods in a base class method is normal practice.
darch
+4  A: 

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.

daotoad
+2  A: 

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();
Eric Strom
+2  A: 

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.

iain
+3  A: 

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).

hobbs