Perl'de miras alma, mevcut paketin hangi paketlerden (sınıflardan) miras aldığını belirten @ISA dizisi aracılığıyla gerçekleştirilir. Bu, birçok diğer dildeki geleneksel OO'dan ziyade, yöntemlerin aranması sırasında ebeveynlerin dinamik olarak eklenmesi gibidir.
Perl'in erken sürümlerinde yerleşik bir nesne yönelimli yaklaşım yoktu. Miras almayı desteklemek için ebeveyn sınıfların sıralandığı @ISA dizisi getirildi. Perl, yöntemleri önce nesnenin kendisinde, ardından sırayla ebeveynlerde arar ki bu da belirli bir esneklik sağlar, ancak kendi özelliklerini de beraberinde getirir.
@ISA aracılığıyla miras alma yöntemleri kapsüllemeyi kolayca bozabilir. Ayrıca, çok düzeyli (çoklu) miras, yöntemlerin beklenmedik çakışmalarını önlemek için ebeveynlerin sırasına dikkat edilmesini gerektirir. Yöntem Arama Sırası (Method Resolution Order) önemli bir hale gelir ve bu her zaman açık olmayabilir, özellikle CPAN modülleri kullanıldığında (örneğin, Moose, base veya parent sınıfları).
Perl'de basit miras alma için @ISA dizisinin beyanı kullanılır:
package Parent; sub hello { print "Ebeveynden merhaba! "; } package Child; our @ISA = ('Parent'); Child::hello(); # Çıktı: Ebeveynden merhaba!
Gerçek projelerde genellikle miras almayı kolaylaştırmak ve daha fazla güvenlik sağlamak için base veya parent pragma kullanılır.
@ISA dizisi aracılığıyla yapılır.BASE pragma veya @ISA dizisinin kullanımı bir ebeveynin yöntemlerini programa başladıktan sonra çocuk sınıfa ekleyebilir mi?
Hayır, Perl mirası scriptin derleme aşamasında belirler, bu nedenle çalıştırma sırasında @ISA'daki değişiklikler daha önce tanımlı nesneleri etkilemez, bu da garip sorunlara yol açabilir.
package Parent; sub hello { print "ebeveyn "; } package Child; our @ISA = ('Parent'); # nesneleri oluşturduktan sonra @ISA'yı değiştirmemek önerilir
@ISA'daki birden fazla ebeveyn sınıfında aynı yöntemi tanımlarsak ne olur?
İlk bulunan yöntem çağrılır ve bu aradaki sıraya bağlıdır. Bu, özellikle çoklu miras durumunda beklenmeyen davranışlara yol açabilir.
package Base1; sub hello { print "Base1 "; } package Base2; sub hello { print "Base2 "; } package Derived; our @ISA = ('Base1', 'Base2'); Derived::hello(); # Çıktı: Base1
Dinamik olarak @ISA'ya sınıf eklemek ve onun yöntemlerine erişmek mümkün mü?
Evet, mümkündür ancak son derece önerilmez, çünkü programın yapısını bozar, yöntemlerin çözümünde hatalara ve çalıştırma zamanı hatalarına yol açabilir.
@ISAyı değiştirmekparent/base pragma kullanmamak, bu da sürdürülebilirliği azaltırBir projede, sınıflara fonksiyonellik eklemek için @ISA dizisini manuel olarak döngü ile değiştirerek dinamik olarak yüklenecek modüllerden yöntemleri miras almaktadır.
Artılar:
Eksiler:
Sınıfı genişletmek için parent pragma kullanılır, ebeveynlerin sırası sıkı bir şekilde kontrol edilerek ve geçersiz kılınabilecek yöntemler açıkça tanımlanır.
Artılar:
Eksiler: