2011-01-12 10 views
9

Bitte geben Sie die Perldoc für oop http://perldoc.perl.org/perlobj.htmlsehen geordnete Klasse von Objekt

Gemäß dem Dokument Bezug SUPER: „Es ist wichtig, dass die SUPER zu beachten, bezieht sich auf die übergeordnete Klasse (n) des aktuellen Pakets und nicht auf die Oberklasse (n) des Objekts. "

Jetzt bin ich in einer Situation, in der ich den SUPER brauche, um auf die Oberklasse (n) des Objekts zu verweisen.

Also, auf der Suche nach einem Weg, um es zu erreichen.

+0

Bitte klären Sie: Was hat Sie davon überzeugt, dass Sie dies können müssen? – darch

Antwort

8

Es ist ziemlich selten, dass Sie wirklich so etwas tun müssen, normalerweise ist es ein Zeichen, dass Sie sich in einem Objekt auf eine Art und Weise mucken, die später wieder beißen wird. Wenn es wirklich so ist, was getan werden muss, können Sie Ihr Paket nur für den Methodenaufruf ändern, um SUPER zu ändern, oder die Methode überschreiben, indem Sie den vollständigen Methodennamen aufrufen.

{ 
    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 [email protected]; 
     # 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(); 

Eine sauberere Option ist für Ihre Methoden, Refactoring, so dass Sie ohne zu versuchen, sowohl die Basisklasse und Unterklasse Methoden zugreifen können das Objekt System zu unterminieren.

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

Oder bieten Sie eine Methode an, um die Basisklassenmethode aufzurufen.

Die beste Antwort hängt wirklich davon ab, was Sie wirklich versuchen, zu tun, warum das erfordert, dass Sie Standardvererbung umgehen.

3

eine Klassenstruktur wie

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

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

und Code wie

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

Sie Gegeben BaseClass::some_method auf dem Objekt aufzurufen. Innerhalb des SubClass Pakets können Sie $object->SUPER::some_method(...) anrufen. Aber, ob Sie in der SubClass Paket sind, können Sie immer rufen explizit die Methode, die Sie wollen als

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

Können Sie mir bitte vorschlagen, wie kann ich die some_method() der BaseClass mit $ -Objekt innerhalb Paket MainPackage aufrufen. – rpg

+0

Genau so, wie ich es geschrieben habe: 'BaseClass :: some_method ($ object)' oder 'BaseClass :: some_method ($ object, @other_args)'. Perls 'object-> METHOD' Konstruktion ist nur syntaktischer Zucker zum Aufrufen von' ObjectClass :: METHOD ($ object) ', wobei' ObjectClass' der Referenztyp von '$ object' ist. – mob

+0

Bitte nicht direkte Manipulation von '@ ISA' empfehlen. – darch

Verwandte Themen