2016-05-21 16 views
2

ich zwei Klassen haben, ist eine der Basisklasse (Mitarbeiter) und der andere seine Unterklasse, die es (Extend) die Codes, von denen erbt sind unten dargestellt:Vererbung in Perl

package Employee; 
require Exporter; 
our @EXPORT = ("getattr"); 

our $private = "This is a class level variable"; 

sub getattr { 
    print "Inside the getattr function of Employee.pm module \n"; 
    $self = shift; 
    $attr = shift; 
    return ($self->{$attr}); 
} 
1; 

===== ===========

package Extend; 

use base qw(Employee); 

sub new { 
    print "Inside new method of Employee.pm \n"; 
    my $class = shift; 
    my %data = (
       name => shift, 
       age => shift, 
       ); 

    bless \%data , $class; 
} 

sub test { 
    print "Inside test method of Extend class \n"; 
} 

1; 

==================

Jetzt habe ich ein Stück Code, der unter Verwendung die Extend-Klasse:

use Extend; 

my $obj = Extend->new("Subhayan",30); 
my $value = $obj->getattr("age"); 
print ("The value of variable age is : $value \n"); 
$obj->test(); 
print "Do i get this : $obj.$private \n"; 

Meine Frage betrifft die Variable $ private, die in der Elternklasse definiert ist. Nach meinem Konzept sollten Vererbungsattribute und Methoden der Elternklasse über das Unterklassenobjekt verfügbar sein. Zum Beispiel läuft die Funktion getattr gut. Aber warum kann ich nicht auf die private Variable $ zugreifen, indem ich das Extend-Objekt der Basisklasse verwende?

Was fehlt mir hier? Kann mir bitte jemand helfen?

+0

Beachten Sie, dass Ihre Verwendung von 'Exporter' hier falsch ist. Exportieren und Vererbung sind zwei völlig getrennte Mechanismen, und wenn Sie objektorientierten Code schreiben, dann wollen Sie nicht 'Exporter'. Es ist auch wahrscheinlich besser, spezifische Accessor-Methoden für die öffentlichen Attribute zu schreiben, da Ihr 'getattr' direkten Zugriff auf alle Instanzvariablen erlaubt, unabhängig davon, ob sie öffentlich oder privat sein sollen. Es ist nur eine geringfügige Verbesserung beim Schreiben von '$ obj -> {'attr'}' im aufrufenden Code – Borodin

Antwort

1

Variablen werden nicht auf dieselbe Weise vererbt wie Subs. Um darauf zuzugreifen, müssen Sie das gesamte Paket Namen angeben (und ja, wenn Sie $private erklären, was Sie brauchen our, nicht my):

print "$Employee::private\n"; 

Es ist viel robuster Accessormethoden zu definieren:

# Employee package 
sub private { 
    return $private; 
} 

... dann in Ihrem Skript:

my $var = private(); 

erben Objekt aus Mitarbeitern Attribute, können Sie tun:

# Employee 

sub new { 
    my $self = bless { 
     dept => 'HR', 
     hours => '9-5', 
    }, shift; 

    return $self; 
} 

# Extend 

sub new { 
    my $class = shift; 
    my $self = $class->SUPER::new; # attrs inherited from Employee 
    $self->{extended} = 1; 
    return $self; 
} 

# script 

my $extend = Extend->new; 

Jetzt $extend wie folgt aussieht:

{ 
    dept => 'HR', 
    hours => '9-5', 
    extended => 1, 
} 

Sie höchstwahrscheinlich nicht dept oder Stunden in der Basisklasse festgelegt würde, wie es für alle Mitarbeiter gelten, aber ich schweife ab.

+0

Helllo @Stevieb. Vielen Dank für Ihre Antwort . Wie funktioniert das Erben von Attributen in Perl? Was sind Attribute einer Klasse in Perl, die vererbt werden können? –

+0

Ich habe meine Antwort so aktualisiert, dass sie eine Möglichkeit enthält, Objektattribute zu übernehmen. – stevieb

+0

Danke @stevieb, aber wie du gezeigt hast, müssen wir die Klasse Employee überhaupt nicht erben. Wenn wir $ class-> SUPER :: new() ersetzen; mit Mitarbeiter-> neu(). Abgesehen von der Verwendung von SUPER und dem Aufruf des Superklassenkonstruktors gibt es keine andere Möglichkeit, wie Attribute automatisch importiert werden, so wie Methoden sind? –