开发者

Referring SUPER to superclass of object

开发者 https://www.devze.com 2023-02-04 14:08 出处:网络
Please see the perldoc for oop http://perldoc.perl.org/perlobj.html As per the document: \"It is important to note that SUPER refers to the superclass(es) of the current package and not to the superc

Please see the perldoc for oop http://perldoc.perl.org/perlobj.html

As per the document: "It is important to note that SUPER refers to the superclass(es) of the current package and not to the superclass(es) of the object."

Now, I am in a situation where I need the SUPER to refer to the 开发者_如何转开发superclass(es) of the object.

So, looking for any way to achieve it.


It's fairly rare that you really need to do something like this, usually it's a sign that your mucking about inside an object in a way that will come back to bite you later. If it's really what needs to be done you can change your package just for the method call to change what SUPER sees, or override method look up by calling the full method name.

{
    package BaseClass;
    sub new { bless \my $self, shift; }
    sub foo { 
        my $self = shift; 
        print "BaseClass::foo()\n";
    }
}
{
    package SubClass;
    our @ISA = qw(BaseClass);
    sub foo { 
        my $self = shift; 
        print "SubClass::foo()\n"; 
        $self->SUPER::foo(); 
    }
}
{
    package ParentClass;
    sub new { bless \my $self, shift; }
    sub bar { 
        my $self = shift; 
        print "ParentClass::bar()\n"; 
    }
}
{
    package ChildClass;
    our @ISA = qw(ParentClass);
    sub foo {
        my $other = SubClass->new();
        print "ChildClass::foo()\n";
        # fails trying to find ParentClass::foo()
        eval { $other->SUPER::foo(); } or warn $@;
        # thinks this is SubClass and finds BaseClass::foo()
        { package SubClass; $other->SUPER::foo(); }
        # if you know the correct class that SUPER::foo() would have called (but this will also work if it was the wrong class)
        $other->BaseClass::foo();
    }
    sub bar { 
        my $self = shift; 
        print "ChildClass::bar()\n"; 
        $self->SUPER::bar(); 
    }
}

my $obj_1 = SubClass->new();
$obj_1->foo();

my $obj_2 = ChildClass->new();
$obj_2->bar();
$obj_2->foo();

A cleaner option is to refactor your methods so that you can access both the base class and sub class methods without trying to subvert the object system.

{
    package BaseClass;
    sub new { bless \my $self, shift; }
    sub foo { 
        my $self = shift; 
        print "BaseClass::foo()\n"; 
    }
}
{
    package SubClass;
    our @ISA = qw(BaseClass);
    sub bar { 
        my $self = shift; 
        print "SubClass::bar()\n"; 
        $self->SUPER::foo(); 
    }
}

my $obj = SubClass->new();
$obj->foo();
$obj->bar();

Or provide a method to call the base class method.

{
    package BaseClass;
    sub new { bless \my $self, shift; }
    sub foo { 
        my $self = shift; 
        print "BaseClass::foo()\n"; 
    }
}
{
    package SubClass;
    our @ISA = qw(BaseClass);
    sub foo { 
        my $self = shift; 
        print "SubClass::foo()\n"; 
        $self->SUPER::foo(); 
    }
    sub bar { 
        my $self = shift; 
        $self->SUPER::foo(); 
    }
}

my $obj = SubClass->new();
$obj->foo();
$obj->bar();

The best answer really depends on what you are really trying to do an why that requires you to work around standard inheritance.


Given a class structure like

package BaseClass;
sub some_method { ... }
...

package SubClass;
our @ISA = qw(BaseClass);
sub some_method { ... }
...

and code like

package MainPackage;
our @ISA = qw(SuperPackage);
my $object = new SubClass(...);

you want to invoke BaseClass::some_method on the object. Inside the SubClass package, you could call $object->SUPER::some_method(...). But whether or not you are inside the SubClass package, you can always explicitly call the method you want as

BaseClass::some_method($object, ...)


I suggest you look into the SUPER module.

0

精彩评论

暂无评论...
验证码 换一张
取 消