PERL'de Nesne Tabanlı Programlama

Perl ve Perl anonim dizileri ve karmalarındaki referansları zaten inceledik. Perl'deki Nesne Yönelimli kavram, büyük ölçüde referanslara ve anonim dizilere ve karmalara dayanır. Nesneye Yönelik Perl'in temel kavramlarını öğrenmeye başlayalım.

Nesne Temelleri

Perl'in nesneleri nasıl işlediği açısından açıklanan üç ana terim vardır. Terimler nesne, sınıf ve yöntemdir.

  • Bir objectPerl içinde yalnızca, hangi sınıfa ait olduğunu bilen bir veri türüne referanstır. Nesne, skaler bir değişkende referans olarak saklanır. Bir skaler yalnızca nesneye bir başvuru içerdiğinden, aynı skaler farklı sınıflarda farklı nesneleri tutabilir.

  • Bir class Perl içinde, nesneleri oluşturmak ve işlemek için gereken ilgili yöntemleri içeren bir pakettir.

  • Bir methodPerl içinde paketle tanımlanan bir alt yordamdır. Yöntemin ilk argümanı, yöntemin geçerli nesneyi veya sınıfı etkilemesine bağlı olarak bir nesne başvurusu veya paket adıdır.

Perl, bir bless() Sonuçta bir nesne haline gelen bir başvuru döndürmek için kullanılan işlev.

Sınıf Tanımlama

Perl'de bir sınıf tanımlamak çok basit. Bir sınıf, en basit haliyle Perl Paketine karşılık gelir. Perl'de bir sınıf oluşturmak için önce bir paket oluşturuyoruz.

Bir paket, tekrar tekrar kullanılabilen, kullanıcı tanımlı değişkenler ve alt rutinlerden oluşan bağımsız bir birimdir.

Perl Paketleri, bir Perl programı içinde alt yordamları ve değişkenleri diğer paketlerdekilerle çakışmaktan bağımsız tutan ayrı bir ad alanı sağlar.

Perl'de Kişi adlı bir sınıfı bildirmek için -

package Person;

Paket tanımının kapsamı dosyanın sonuna veya başka bir paket anahtar sözcüğüyle karşılaşılana kadar uzanır.

Nesne Oluşturma ve Kullanma

Bir sınıfın bir örneğini (bir nesne) oluşturmak için bir nesne yapıcısına ihtiyacımız var. Bu kurucu, paket içinde tanımlanan bir yöntemdir. Çoğu programcı, bu nesne yapıcı yöntemini yeni olarak adlandırmayı seçer, ancak Perl'de herhangi bir adı kullanabilirsiniz.

Perl'de herhangi bir Perl değişkenini bir nesne olarak kullanabilirsiniz. Çoğu Perl programcısı, dizilere veya karmalara başvuruları seçer.

Perl hash referansı kullanarak Person sınıfımız için kurucumuzu oluşturalım. Bir nesne oluştururken, bir pakette nesne referansı döndüren bir alt yordam olan bir kurucu sağlamanız gerekir. Nesne başvurusu, paketin sınıfına bir başvuru kutsayarak oluşturulur. Örneğin -

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;
}

Şimdi nasıl bir Object oluşturacağımızı görelim.

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

Herhangi bir sınıf değişkenine herhangi bir değer atamak istemiyorsanız, oluşturucunuzda basit karma kullanabilirsiniz. Örneğin -

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

Yöntemleri Tanımlama

Diğer nesne yönelimli diller, bir programcının bir nesne verilerini doğrudan değiştirmesini önlemek için veri güvenliği konseptine sahiptir ve bunlar, nesne verilerini değiştirmek için erişim yöntemleri sağlar. Perl'de özel değişkenler yoktur, ancak yine de nesne verilerini işlemek için yardımcı yöntemler kavramını kullanabiliriz.

Kişinin adını almak için bir yardımcı yöntem tanımlayalım -

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

Kişinin adını belirlemek için başka bir yardımcı işlev -

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

Şimdi eksiksiz bir örneğe bakalım: Kişi paketini ve yardımcı işlevleri Person.pm dosyasında saklayın.

#!/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;

Şimdi Employee.pl dosyasındaki Person nesnesini aşağıdaki gibi kullanalım -

#!/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";

Yukarıdaki programı çalıştırdığımızda, aşağıdaki sonucu verir -

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

Miras

Nesne yönelimli programlama, miras adı verilen çok iyi ve kullanışlı bir konsepte sahiptir. Kalıtım, bir üst sınıfın özelliklerinin ve yöntemlerinin alt sınıflar tarafından kullanılabilir olacağı anlamına gelir. Böylece aynı kodu tekrar tekrar yazmak zorunda değilsiniz, sadece bir ebeveyn sınıfı miras alabilirsiniz.

Örneğin, Person'dan miras kalan bir Çalışan sınıfımız olabilir. Çalışan bir kişi olduğu için buna "isa" ilişkisi denir. Perl'in bu konuda yardımcı olması için @ISA adlı özel bir değişkeni vardır. @ISA kalıtımı yönetir (yöntem).

Miras kullanılırken dikkat edilmesi gereken önemli noktalar şunlardır:

  • Perl, verilen yöntem veya öznitelik, yani değişken için belirtilen nesnenin sınıfını arar.

  • Perl, nesne sınıfının @ISA dizisinde tanımlanan sınıfları arar.

  • Adım 1 veya 2'de hiçbir yöntem bulunmazsa, @ISA ağacında bulunursa Perl bir AUTOLOAD alt yordamı kullanır.

  • Eşleşen bir yöntem hala bulunamazsa, Perl yöntemi, standart Perl kitaplığının bir parçası olarak gelen UNIVERSAL sınıfı (paket) içinde arar.

  • Yöntem hala bulunamazsa, Perl pes eder ve bir çalışma zamanı istisnası oluşturur.

Dolayısıyla, Person sınıfımızdan yöntemleri ve öznitelikleri devralacak yeni bir Employee sınıfı oluşturmak için, aşağıdaki gibi kodlama yapıyoruz: Bu kodu Employee.pm'de saklayın.

#!/usr/bin/perl

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

Artık Çalışan Sınıfı, Person sınıfından miras alınan tüm yöntemlere ve özniteliklere sahiptir ve bunları aşağıdaki gibi kullanabilirsiniz: Test etmek için main.pl dosyasını kullanın -

#!/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";

Yukarıdaki programı çalıştırdığımızda, aşağıdaki sonucu verir -

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

Yöntemi Geçersiz Kılma

Çalışan çocuk sınıfı, Person üst sınıfından tüm yöntemleri devralır. Ancak, çocuk sınıfınızda bu yöntemleri geçersiz kılmak istiyorsanız, bunu kendi uygulamanızı vererek yapabilirsiniz. Ek işlevlerinizi alt sınıfta ekleyebilir veya üst sınıfında var olan bir yöntemin işlevselliğini ekleyebilir veya değiştirebilirsiniz. Aşağıdaki gibi yapılabilir: Employee.pm dosyasını değiştirin.

#!/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;

Şimdi yine main.pl dosyamızda Employee nesnesini kullanmayı deneyelim ve çalıştıralım.

#!/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";

Yukarıdaki programı çalıştırdığımızda, aşağıdaki sonucu verir -

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.

Varsayılan Otomatik Yükleme

Perl, diğer programlama dillerinde bulamayacağınız bir özellik sunar: varsayılan bir alt program. Bu, adı verilen bir işlevi tanımlarsanız,AUTOLOAD(),daha sonra tanımlanmamış alt programlara yapılan herhangi bir çağrı AUTOLOAD () işlevini otomatik olarak çağıracaktır. Eksik alt yordamın adına bu alt yordam içinde $ AUTOLOAD olarak erişilebilir.

Varsayılan otomatik yükleme işlevi, hata işleme için çok kullanışlıdır. İşte AUTOLOAD'ı uygulamak için bir örnek, bu işlevi kendi yönteminizle uygulayabilirsiniz.

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);
   }
}

Yıkıcılar ve Çöp Toplama

Daha önce nesne yönelimli programlama kullanarak programladıysanız, bir program oluşturma ihtiyacının farkında olacaksınız. destructornesneyi kullanmayı bitirdiğinizde, nesneye ayrılan belleği boşaltmak için. Perl, nesne kapsam dışına çıkar çıkmaz bunu sizin için otomatik olarak yapar.

İmha edicinizi uygulamak istiyorsanız, ki bu da dosyaları kapatmakla veya fazladan bazı işlemler yapmakla ilgilenmelidir, o zaman özel bir yöntem tanımlamanız gerekir. DESTROY. Bu yöntem, Perl kendisine ayrılan belleği serbest bırakmadan hemen önce nesneye çağrılacaktır. Diğer tüm açılardan, DESTROY yöntemi tıpkı diğer yöntemler gibidir ve bu yöntem içinde istediğiniz mantığı uygulayabilirsiniz.

Bir yıkıcı yöntemi, aşağıdaki durumlarda otomatik olarak çağrılacak olan DESTROY adlı bir üye işlevdir (alt yordam) -

  • Nesne referansının değişkeni kapsam dışına çıktığında.
  • Nesne başvurusunun değişkeni tanımsız olduğunda.
  • Komut dosyası bittiğinde
  • Perl yorumlayıcısı sona erdiğinde

Örneğin, aşağıdaki DESTROY yöntemini sınıfınıza koyabilirsiniz -

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

Nesne Tabanlı Perl Örneği

İşte Perl'in Nesneye Dayalı Kavramlarını anlamanıza yardımcı olacak bir başka güzel örnek. Bu kaynak kodunu herhangi bir perl dosyasına koyun ve çalıştırın.

#!/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

Yukarıdaki programı çalıştırdığımızda, aşağıdaki sonucu verir -

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