Objektorientierte Programmierung in PERL

Wir haben bereits Referenzen in anonymen Perl- und Perl-Arrays und -Hashes untersucht. Das objektorientierte Konzept in Perl basiert stark auf Referenzen und anonymen Arrays und Hashes. Beginnen wir mit dem Erlernen grundlegender Konzepte von objektorientiertem Perl.

Objektgrundlagen

Es gibt drei Hauptbegriffe, die unter dem Gesichtspunkt erläutert werden, wie Perl mit Objekten umgeht. Die Begriffe sind Objekt, Klasse und Methode.

  • Ein objectIn Perl wird lediglich auf einen Datentyp verwiesen, der weiß, zu welcher Klasse er gehört. Das Objekt wird als Referenz in einer skalaren Variablen gespeichert. Da ein Skalar nur einen Verweis auf das Objekt enthält, kann derselbe Skalar verschiedene Objekte in verschiedenen Klassen enthalten.

  • EIN class In Perl befindet sich ein Paket, das die entsprechenden Methoden zum Erstellen und Bearbeiten von Objekten enthält.

  • EIN methodInnerhalb von Perl befindet sich eine Unterroutine, die mit dem Paket definiert wird. Das erste Argument für die Methode ist eine Objektreferenz oder ein Paketname, je nachdem, ob die Methode das aktuelle Objekt oder die Klasse beeinflusst.

Perl bietet eine bless() Funktion, mit der eine Referenz zurückgegeben wird, die letztendlich zu einem Objekt wird.

Eine Klasse definieren

Es ist sehr einfach, eine Klasse in Perl zu definieren. Eine Klasse entspricht einem Perl-Paket in seiner einfachsten Form. Um eine Klasse in Perl zu erstellen, erstellen wir zunächst ein Paket.

Ein Paket ist eine in sich geschlossene Einheit von benutzerdefinierten Variablen und Unterprogrammen, die immer wieder verwendet werden können.

Perl-Pakete bieten einen separaten Namespace innerhalb eines Perl-Programms, der Unterprogramme und Variablen unabhängig von Konflikten mit denen in anderen Paketen hält.

Um eine Klasse mit dem Namen Person in Perl zu deklarieren, tun wir:

package Person;

Der Umfang der Paketdefinition erstreckt sich bis zum Ende der Datei oder bis ein anderes Paketschlüsselwort gefunden wird.

Objekte erstellen und verwenden

Um eine Instanz einer Klasse (eines Objekts) zu erstellen, benötigen wir einen Objektkonstruktor. Dieser Konstruktor ist eine im Paket definierte Methode. Die meisten Programmierer benennen diese Objektkonstruktormethode neu, aber in Perl können Sie einen beliebigen Namen verwenden.

Sie können jede Art von Perl-Variable als Objekt in Perl verwenden. Die meisten Perl-Programmierer wählen entweder Verweise auf Arrays oder Hashes.

Lassen Sie uns unseren Konstruktor für unsere Person-Klasse mithilfe einer Perl-Hash-Referenz erstellen. Beim Erstellen eines Objekts müssen Sie einen Konstruktor angeben, bei dem es sich um eine Unterroutine in einem Paket handelt, die eine Objektreferenz zurückgibt. Die Objektreferenz wird erstellt, indem eine Referenz auf die Klasse des Pakets gesegnet wird. Zum Beispiel -

package Person;
sub new {
   my $class = shift;
   my $self = {
      _firstName => shift,
      _lastName  => shift,
      _ssn       => shift,
   };
   # Print all the values just for clarification.
   print "First Name is $self->{_firstName}\n";
   print "Last Name is $self->{_lastName}\n";
   print "SSN is $self->{_ssn}\n";
   bless $self, $class;
   return $self;
}

Lassen Sie uns nun sehen, wie Sie ein Objekt erstellen.

$object = new Person( "Mohammad", "Saleem", 23234345);

Sie können einfachen Hash in Ihrem Konstruktor verwenden, wenn Sie keiner Klassenvariablen einen Wert zuweisen möchten. Zum Beispiel -

package Person;
sub new {
   my $class = shift;
   my $self = {};
   bless $self, $class;
   return $self;
}

Methoden definieren

Andere objektorientierte Sprachen haben das Konzept der Datensicherheit, um zu verhindern, dass ein Programmierer Objektdaten direkt ändert, und sie bieten Zugriffsmethoden zum Ändern von Objektdaten. Perl hat keine privaten Variablen, aber wir können immer noch das Konzept der Hilfsmethoden verwenden, um Objektdaten zu manipulieren.

Definieren wir eine Hilfsmethode, um den Vornamen einer Person zu erhalten.

sub getFirstName {
   return $self->{_firstName};
}

Eine weitere Hilfsfunktion zum Festlegen des Vornamens einer Person -

sub setFirstName {
   my ( $self, $firstName ) = @_;
   $self->{_firstName} = $firstName if defined($firstName);
   return $self->{_firstName};
}

Schauen wir uns nun ein vollständiges Beispiel an: Behalten Sie das Personenpaket und die Hilfsfunktionen in der Person.pm-Datei.

#!/usr/bin/perl 

package Person;

sub new {
   my $class = shift;
   my $self = {
      _firstName => shift,
      _lastName  => shift,
      _ssn       => shift,
   };
   # Print all the values just for clarification.
   print "First Name is $self->{_firstName}\n";
   print "Last Name is $self->{_lastName}\n";
   print "SSN is $self->{_ssn}\n";
   bless $self, $class;
   return $self;
}
sub setFirstName {
   my ( $self, $firstName ) = @_;
   $self->{_firstName} = $firstName if defined($firstName);
   return $self->{_firstName};
}

sub getFirstName {
   my( $self ) = @_;
   return $self->{_firstName};
}
1;

Verwenden wir nun das Objekt Person in der Datei employee.pl wie folgt:

#!/usr/bin/perl

use Person;

$object = new Person( "Mohammad", "Saleem", 23234345);
# Get first name which is set using constructor.
$firstName = $object->getFirstName();

print "Before Setting First Name is : $firstName\n";

# Now Set first name using helper function.
$object->setFirstName( "Mohd." );

# Now get first name set by helper function.
$firstName = $object->getFirstName();
print "Before Setting First Name is : $firstName\n";

Wenn wir das obige Programm ausführen, wird das folgende Ergebnis erzeugt:

First Name is Mohammad
Last Name is Saleem
SSN is 23234345
Before Setting First Name is : Mohammad
Before Setting First Name is : Mohd.

Erbe

Objektorientierte Programmierung hat ein sehr gutes und nützliches Konzept, das als Vererbung bezeichnet wird. Vererbung bedeutet einfach, dass Eigenschaften und Methoden einer übergeordneten Klasse den untergeordneten Klassen zur Verfügung stehen. Sie müssen also nicht immer wieder denselben Code schreiben, sondern können einfach eine übergeordnete Klasse erben.

Zum Beispiel können wir eine Klasse Employee haben, die von Person erbt. Dies wird als "isa" -Beziehung bezeichnet, da ein Mitarbeiter eine Person ist. Perl hat eine spezielle Variable, @ISA, um dabei zu helfen. @ISA regelt die (Methoden-) Vererbung.

Im Folgenden sind die wichtigen Punkte aufgeführt, die bei der Verwendung der Vererbung zu beachten sind:

  • Perl durchsucht die Klasse des angegebenen Objekts nach der angegebenen Methode oder dem angegebenen Attribut, dh nach der Variablen.

  • Perl durchsucht die im @ ISO-Array der Objektklasse definierten Klassen.

  • Wenn in Schritt 1 oder 2 keine Methode gefunden wird, verwendet Perl eine AUTOLOAD-Unterroutine, sofern eine im @ISA-Baum gefunden wird.

  • Wenn eine passende Methode immer noch nicht gefunden werden kann, sucht Perl nach der Methode in der UNIVERSAL-Klasse (Paket), die Teil der Standard-Perl-Bibliothek ist.

  • Wenn die Methode immer noch nicht gefunden wurde, gibt Perl auf und löst eine Laufzeitausnahme aus.

Um eine neue Employee-Klasse zu erstellen, die Methoden und Attribute von unserer Person-Klasse erbt, codieren wir einfach wie folgt: Behalten Sie diesen Code in Employee.pm bei.

#!/usr/bin/perl

package Employee;
use Person;
use strict;
our @ISA = qw(Person);    # inherits from Person

Jetzt verfügt die Mitarbeiterklasse über alle Methoden und Attribute, die von der Personenklasse geerbt wurden, und Sie können sie wie folgt verwenden: Verwenden Sie die Datei main.pl, um sie zu testen -

#!/usr/bin/perl

use Employee;

$object = new Employee( "Mohammad", "Saleem", 23234345);
# Get first name which is set using constructor.
$firstName = $object->getFirstName();

print "Before Setting First Name is : $firstName\n";

# Now Set first name using helper function.
$object->setFirstName( "Mohd." );

# Now get first name set by helper function.
$firstName = $object->getFirstName();
print "After Setting First Name is : $firstName\n";

Wenn wir das obige Programm ausführen, wird das folgende Ergebnis erzeugt:

First Name is Mohammad
Last Name is Saleem
SSN is 23234345
Before Setting First Name is : Mohammad
Before Setting First Name is : Mohd.

Überschreiben der Methode

Die untergeordnete Klasse Employee erbt alle Methoden von der übergeordneten Klasse Person. Wenn Sie diese Methoden in Ihrer untergeordneten Klasse überschreiben möchten, können Sie dies tun, indem Sie Ihre eigene Implementierung angeben. Sie können Ihre zusätzlichen Funktionen in der untergeordneten Klasse hinzufügen oder die Funktionalität einer vorhandenen Methode in der übergeordneten Klasse hinzufügen oder ändern. Dies kann wie folgt erfolgen: Ändern Sie die Datei Employee.pm.

#!/usr/bin/perl

package Employee;
use Person;
use strict;
our @ISA = qw(Person);    # inherits from Person

# Override constructor
sub new {
   my ($class) = @_;

   # Call the constructor of the parent class, Person.
   my $self = $class->SUPER::new( $_[1], $_[2], $_[3] );
   # Add few more attributes
   $self->{_id}   = undef;
   $self->{_title} = undef;
   bless $self, $class;
   return $self;
}

# Override helper function
sub getFirstName {
   my( $self ) = @_;
   # This is child class function.
   print "This is child class helper function\n";
   return $self->{_firstName};
}

# Add more methods
sub setLastName{
   my ( $self, $lastName ) = @_;
   $self->{_lastName} = $lastName if defined($lastName);
   return $self->{_lastName};
}

sub getLastName {
   my( $self ) = @_;
   return $self->{_lastName};
}

1;

Versuchen wir nun erneut, das Employee-Objekt in unserer Datei main.pl zu verwenden und auszuführen.

#!/usr/bin/perl

use Employee;

$object = new Employee( "Mohammad", "Saleem", 23234345);
# Get first name which is set using constructor.
$firstName = $object->getFirstName();

print "Before Setting First Name is : $firstName\n";

# Now Set first name using helper function.
$object->setFirstName( "Mohd." );

# Now get first name set by helper function.
$firstName = $object->getFirstName();
print "After Setting First Name is : $firstName\n";

Wenn wir das obige Programm ausführen, wird das folgende Ergebnis erzeugt:

First Name is Mohammad
Last Name is Saleem
SSN is 23234345
This is child class helper function
Before Setting First Name is : Mohammad
This is child class helper function
After Setting First Name is : Mohd.

Standard-Autoloading

Perl bietet eine Funktion, die Sie in keiner anderen Programmiersprache finden würden: eine Standard-Unterroutine. Das heißt, wenn Sie eine aufgerufene Funktion definierenAUTOLOAD(),Alle Aufrufe undefinierter Unterprogramme rufen dann automatisch die Funktion AUTOLOAD () auf. Der Name der fehlenden Unterroutine ist in dieser Unterroutine als $ AUTOLOAD verfügbar.

Die Standardfunktion zum automatischen Laden ist sehr nützlich für die Fehlerbehandlung. Hier ist ein Beispiel für die Implementierung von AUTOLOAD. Sie können diese Funktion auf Ihre eigene Weise implementieren.

sub AUTOLOAD {
   my $self = shift;
   my $type = ref ($self) || croak "$self is not an object";
   my $field = $AUTOLOAD;
   $field =~ s/.*://;
   unless (exists $self->{$field}) {
      croak "$field does not exist in object/class $type";
   }
   if (@_) {
      return $self->($name) = shift;
   } else {
      return $self->($name);
   }
}

Zerstörer und Müllabfuhr

Wenn Sie zuvor mit objektorientierter Programmierung programmiert haben, sind Sie sich der Notwendigkeit bewusst, eine zu erstellen destructorum den dem Objekt zugewiesenen Speicher freizugeben, wenn Sie es nicht mehr verwenden. Perl erledigt dies automatisch für Sie, sobald das Objekt den Gültigkeitsbereich verlässt.

Wenn Sie Ihren Destruktor implementieren möchten, der sich um das Schließen von Dateien oder eine zusätzliche Verarbeitung kümmern soll, müssen Sie eine spezielle Methode mit dem Namen definieren DESTROY. Diese Methode wird für das Objekt aufgerufen, kurz bevor Perl den ihm zugewiesenen Speicher freigibt. Im Übrigen ist die DESTROY-Methode genau wie jede andere Methode, und Sie können jede gewünschte Logik in diese Methode implementieren.

Eine Destruktormethode ist einfach eine Elementfunktion (Unterroutine) namens DESTROY, die in den folgenden Fällen automatisch aufgerufen wird:

  • Wenn die Variable der Objektreferenz den Gültigkeitsbereich verlässt.
  • Wenn die Variable der Objektreferenz nicht definiert ist.
  • Wenn das Skript beendet wird
  • Wenn der Perl-Interpreter beendet wird

Zum Beispiel können Sie einfach die folgende Methode DESTROY in Ihre Klasse einfügen:

package MyClass;
...
sub DESTROY {
   print "MyClass::DESTROY called\n";
}

Objektorientiertes Perl-Beispiel

Hier ist ein weiteres schönes Beispiel, das Ihnen hilft, objektorientierte Konzepte von Perl zu verstehen. Fügen Sie diesen Quellcode in eine Perl-Datei ein und führen Sie ihn aus.

#!/usr/bin/perl

# Following is the implementation of simple Class.
package MyClass;

sub new {
   print "MyClass::new called\n";
   my $type = shift;            # The package/type name
   my $self = {};               # Reference to empty hash
   return bless $self, $type;   
}

sub DESTROY {
   print "MyClass::DESTROY called\n";
}

sub MyMethod {
   print "MyClass::MyMethod called!\n";
}


# Following is the implemnetation of Inheritance.
package MySubClass;

@ISA = qw( MyClass );

sub new {
   print "MySubClass::new called\n";
   my $type = shift;            # The package/type name
   my $self = MyClass->new;     # Reference to empty hash
   return bless $self, $type;  
}

sub DESTROY {
   print "MySubClass::DESTROY called\n";
}

sub MyMethod {
   my $self = shift;
   $self->SUPER::MyMethod();
   print "   MySubClass::MyMethod called!\n";
}

# Here is the main program using above classes.
package main;

print "Invoke MyClass method\n";

$myObject = MyClass->new();
$myObject->MyMethod();

print "Invoke MySubClass method\n";

$myObject2 = MySubClass->new();
$myObject2->MyMethod();

print "Create a scoped object\n";
{
   my $myObject2 = MyClass->new();
}
# Destructor is called automatically here

print "Create and undef an object\n";
$myObject3 = MyClass->new();
undef $myObject3;

print "Fall off the end of the script...\n";
# Remaining destructors are called automatically here

Wenn wir das obige Programm ausführen, wird das folgende Ergebnis erzeugt:

Invoke MyClass method
MyClass::new called
MyClass::MyMethod called!
Invoke MySubClass method
MySubClass::new called
MyClass::new called
MyClass::MyMethod called!
MySubClass::MyMethod called!
Create a scoped object
MyClass::new called
MyClass::DESTROY called
Create and undef an object
MyClass::new called
MyClass::DESTROY called
Fall off the end of the script...
MyClass::DESTROY called
MySubClass::DESTROY called