Ссылается SUPER на суперкласс объекта - PullRequest
10 голосов
/ 12 января 2011

Пожалуйста, смотрите perldoc для oop http://perldoc.perl.org/perlobj.html

Согласно документу: «Важно отметить, что SUPER относится к суперклассу (ам) текущего пакета, а не к суперклассу (ам)объекта. "

Теперь я нахожусь в ситуации, когда мне нужно, чтобы SUPER ссылался на суперкласс (ы) объекта.

Итак, я ищу какой-либо способ его достижения..

Ответы [ 3 ]

9 голосов
/ 12 января 2011

Довольно редко вам действительно нужно делать что-то подобное, обычно это признак того, что вы копаетесь в объекте таким образом, что вы снова будете кусать вас позже.Если это действительно то, что нужно сделать, вы можете изменить свой пакет только для вызова метода, чтобы изменить то, что видит SUPER, или переопределить поиск метода, вызвав полное имя метода.

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

Более чистым вариантом являетсяреорганизовать ваши методы, чтобы вы могли обращаться к методам как базового класса, так и подкласса, не пытаясь разрушить объектную систему.

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

Или предоставить метод для вызова метода базового класса.

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

Лучший ответ на самом деле зависит от того, что вы действительно пытаетесь сделать, и почему для этого необходимо обходить стандартное наследование.

3 голосов
/ 12 января 2011

Учитывая структуру класса, такую ​​как

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

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

и код типа

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

, вы хотите вызвать BaseClass::some_method для объекта.Внутри пакета SubClass вы можете позвонить $object->SUPER::some_method(...).Но независимо от того, находитесь ли вы внутри пакета SubClass, вы всегда можете явно вызвать нужный метод как

BaseClass::some_method($object, ...)
1 голос
/ 12 января 2011

Я предлагаю вам заглянуть в модуль SUPER .

...