Python 3 - Nesne Tabanlı Programlama

Fatih Küçükkarakurt

Fatih Küçükkarakurt

16 min read

Nesne tabanlı programlama (OOP), ilgili özellikleri ve davranışları tek tek nesneler halinde bir araya getirerek programı yapılandırma yöntemidir . Bu makalede, Python'da nesne yönelimli programlamanın temellerini anlatmaya çalışacağım.

Bu makalede, aşağıdakileri öğrenmiş olacaksınız:

  • Bir sınıf oluşturmak
  • Yeni nesneler oluşturmak için sınıfları kullanmak
  • Sınıf mirasına sahip model sistemlerini anlamak

Python'da Nesne Tabanlı Programlama Nedir?

Nesne tabanlı programlama, özelliklerin ve davranışların ayrı nesneler halinde bir araya getirilmesi için programları yapılandırmanın bir yolunu sağlayan programlama paradigmasıdır.

Örneğin, nesneler ile kişileri ilişkilendirmek istersek, kişilerin yüz şekilleri, göz renkleri, adresleri, yaşları vb özelliklerini kullanabiliriz.

Başka bir deyişle, nesne tabanlı programlama; somut, gerçek dünya var olan nesnelerin yanı sıra şirketler ve çalışanlar, öğrenciler ve öğretmenler gibi nesneler arasındaki ilişkileri modellemeye yönelik bir yaklaşımdır. OOP, gerçek dünyadaki varlıkları, kendileriyle ilişkili bazı verilere sahip olan ve belirli işlevleri gerçekleştirebilen yazılım nesneleri olarak modeller.

Diğer bir yaygın programlama paradigması, bir programı, bir görevi tamamlamak için sıralı olarak akan işlevler ve kod blokları biçiminde bir dizi adım sağlayan prosedürel programlamadır .

Ana fikir, nesnelerin Python'da nesne tabanlı programlamanın merkezinde yer almasıdır, prosedürel programlamada olduğu gibi yalnızca verileri temsil etmekle kalmaz, aynı zamanda programın genel yapısında da bulunur.

Python'da bir Sınıf Tanımlayın

Sayılar, dizeler ve listeler gibi basit veri yapıları, sırasıyla bir ürünün maliyeti, bir şiirin adı veya en sevdiğiniz renkler gibi basit bilgi parçalarını temsil edecek şekilde tasarlanmıştır. Peki ya daha karmaşık bir şeyi temsil etmek istiyorsanız?

Örneğin, bir organizasyondaki çalışanları izlemek istediğinizi varsayalım. Her çalışanın adı, yaşı, pozisyonu ve çalışmaya başladığı yıl gibi bazı temel bilgileri kaydetmeniz gerekir.

Bunu yapmanın bir yolu, sorunu liste şeklinde sembolize etmektir:

fatih = ["Fatih Karakurt", 25, "Developer", 2019]
ayse = ["Ayse Ozturk", 26, "Designer"]
ali = ["Ali Karaca", "Manager" , 2016]

Aslında bu yaklaşımda bazı sorunlar var.

Birincisi çok daha büyük veri kümelerini yönetmenin gerçekten çok zor olacağı gerçeği. Binlerce kişinin çalıştığı bir işletme için bunu yapmak gerçekten zor olurdu.

İkincisi, her çalışanın listede aynı sayıda öğeye sahip olmaması, hatalara neden olabilir. Gördüğünüz gibi yukardaki kod parçacığında her çalışan için her veri yok.

İşte bu yüzden, bu tür yönetmesi zor kodları sürdürülebilir ve daha kullanışlı hale getirmenin harika bir yolu var. Elbette sınıfları kullanmak.

Sınıflar ve Örnekler

Sınıflar, kullanıcı tanımlı veri yapıları oluşturmak için kullanılır. Sınıflar, sınıftan oluşturulan bir nesnenin verileriyle gerçekleştirebileceği davranışları ve eylemleri tanımlayan yöntemler adı verilen işlevleri tanımlar.

Örnek olması amacıyla bu makalede Kopek adında bir sınıf oluşturacağız. Bu sınıfın içerisinde bir köpeğin sahip olabileceği özellikler ve davranışlar hakkında bazı bilgileri depolamaya çalışacağız.

Sınıf, bir şeyin nasıl tanımlanması gerektiğine dair bir plandır. Aslında herhangi bir veri içermez. Kopek sınıfı, bir köpeği tanımlamak için isim ve yaşın gerekli olduğunu belirtir, ancak herhangi bir köpeğin adını veya yaşını içermez.

Sınıf plan iken, örnek bir sınıftan oluşturulan ve gerçek verileri içeren bir nesnedir. Kopek sınıfının örneği artık bir plan değildir. 2 yaşındaki Casper ismine sahip gerçek bir köpektir.

Başka bir deyişle, sınıf bir form veya anket gibidir. Tıpkı birçok kişinin aynı formu kendi benzersiz bilgileriyle doldurabilmesi gibi, birçok örnek tek bir sınıftan oluşturulabilir.

Bir Sınıf Nasıl Tanımlanır

Tüm sınıf tanımları, sınıfın adı ve iki nokta üst üste ile devam eden class anahtar sözcüğü ile başlar. Sınıf tanımının altında girintili olan herhangi bir kod, sınıfın gövdesinin bir parçası olarak kabul edilir.

class Kopek:
    pass

Kopek sınıfının gövdesi tek bir ifadeden oluşur: pass anahtar sözcüğü. pass, genellikle kodun sonunda nereye gideceğini belirten bir yer tutucu olarak kullanılır. Python bir hata olmadan bu kodu çalıştırmanıza izin verir.

Not: Python sınıf adları, geleneksel olarak büyük harfle başlayarak yazılır. Örneğin; YazilimGelistirmeDersleri, PythonOgreniyorum...

Oluşturduğumuz Kopek sınıfı şu anda pek ilginç değil, bu yüzden tüm Kopek nesnelerinin sahip olması gereken bazı özellikleri tanımlayarak biraz daha iyi hale getirelim. İsim, yaş, kürk rengi ve cins gibi seçebileceğimiz bir dizi özellik vardır. İşleri basitleştirmek için sadece ismi ve yaşı kullanacağız.

Tüm Kopek nesnelerinin sahip olması gereken özellikler, .__init__() adlı bir yöntemde tanımlanmıştır. Yeni bir Kopek nesnesi oluşturulduğunda,.__init__(), nesnenin özelliklerinin değerlerini atayarak nesnenin başlangıç durumunu ayarlar. Yani, .__init__(), sınıfın her yeni örneğini başlatacaktır.

.__init__()'e istediğiniz sayıda parametre verebilirsiniz, ancak ilk parametre her zaman self adında bir değişken olacaktır. Yeni bir sınıf örneği oluşturulduğunda, nesne üzerinde yeni özniteliklerin tanımlanabilmesi için örnek, .__init__() içindeki self parametresine otomatik olarak aktarılır.

Şimdi Kopek sınıfını .isim ve .yas niteliklerini oluşturan bir .__init__() yöntemiyle güncelleyelim:

class Kopek:
     def __init__(self, isim, yas):
        self.isim= isim
        self.yas= yas

.__init__() yönteminde girintili dört boşluk olduğuna dikkat edin. Yöntemin gövdesi sekiz boşlukla girintilidir. Bu girinti hayati derecede önemlidir. Python'a .__init__() yönteminin Kopek sınıfına ait olduğunu söyler.

.__init__() gövdesinde, öznitelik kullanan iki ifade vardır:

  1. self.isim = isim, isimadında bir öznitelik oluşturur ve buna isim parametresinin değerini atar.
  2. self.yas= yas, yas adında bir öznitelik oluşturur ve buna yaş parametresinin değerini atar.

.__init__() içinde oluşturulan özniteliklere örnek öznitelikler denir. Bir örnek özniteliğinin değeri, sınıfın belirli bir örneğine özgüdür. Tüm Kopek nesnelerinin bir ismi ve bir yaşı vardır, ancak ìsim ve yas niteliklerinin değerleri, Köpek örneğine bağlı olarak değişecektir.

Öte yandan, sınıf öznitelikleri, tüm sınıf örnekleri için aynı değere sahip özniteliklerdir. .__init__() dışındaki bir değişken adına bir değer atayarak bir sınıf niteliği tanımlayabilirsiniz.

Örneğin, aşağıdaki Kopek sınıfı, "Labrador" değerine sahip tür adında bir sınıf özniteliğine sahiptir:

class Kopek:
    ## Sınıf Özelligi
    species = "Labrador"

    def __init__(self, isim, yas):
        self.isim= isim
        self.yas= yas

Sınıf öznitelikleri, doğrudan sınıf adının ilk satırının altında tanımlanır ve dört boşlukla girintilidir. Her zaman bir başlangıç değeri atanmalıdır. Sınıfın bir örneği oluşturulduğunda, sınıf öznitelikleri otomatik olarak oluşturulur ve başlangıç değerlerine atanır.

Yani her sınıf örneği için aynı değere sahip olması gereken özellikleri tanımlamak amacı taşıyorsanız, sınıf niteliklerini kullanın. Bir örnekten diğerine değişen özellikler kullanmak istiyorsanız, örnek niteliklerini kullanın.

Artık bir Kopeksınıfımız olduğuna göre, bu işi biraz daha ileri götürebiliriz.

Python'da Bir Nesnenin Örneğini Oluşturun

Kullandığınız IDLE penceresini açın ve aşağıdakileri yazın:

>>>class Kopek:
...     pass

Bununla birlikte, nitelik veya yöntem içermeyen yeni bir Kopek sınıfı oluşturmuş olacaksınız.

Bir sınıftan yeni bir nesne oluşturmaya, nesnenin somutlaştırılması denir. Sınıfın adını yazıp ardından parantezleri açıp kapatarak yeni bir Kopek nesnesi oluşturabilirsiniz:

>>>Kopek()
<__main__.Kopek object at 0x108602d50>

Artık 0x108602d50'de yeni bir Kopek nesneniz var. Bu tuhaf görünümlü harf ve sayı dizisi, Kopek nesnesinin bilgisayarınızın belleğinde nerede depolandığını gösteren bir bellek adresidir. Ekranınızda gördüğünüz adresin farklı olacağını unutmayın.

Şimdi ikinci bir Kopek nesnesi oluşturalım:

>>> Kopek()
<__main__.Kopek object at 0x0004ccc90>

Yeni Kopekörneği, farklı bir bellek adresinde bulunur. Bunun nedeni, tamamen yeni bir örnek olması ve örneklediğiniz ilk Kopek nesnesinden tamamen benzersiz olmasıdır.

Bunu başka bir şekilde görmek için aşağıdakileri yazın:

>>> a = Kopek()
>>> b = Kopek()
>>> a == b
False

Bu kodda, iki yeni Kopek nesnesi oluşturursunuz ve bunları a ve b değişkenlerine atarsınız. == operatörünü kullanarak a ve b'yi karşılaştırdığınızda sonuç False olur. a ve b'nin her ikisi de Kopek sınıfının örnekleri olsa da, bellekte iki farklı nesneyi temsil ederler.

Sınıf ve Örnek Nitelikleri

Şimdi .species adlı bir sınıf özniteliğine ve .isim ve .yas adlı iki örnek özniteliğe sahip yeni bir Kopek sınıfı oluşturun:

>>> class Kopek:
...     species = "Köpek familyası"
...     def __init__(self, isim, yas):
...         self.isim= isim
...         self.yas= yas

Bu Kopeksınıfının nesnelerini somutlaştırmak amacıyla, isim ve yas için değerler sağlamanız gerekir. Bunu yapmazsanız, Python, TypeError sonucu verir:

>>> Kopek()
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    Kopek()
TypeError: __init__() missing 2 required positional arguments: 'isim' and 'yas'

isim ve yasparametrelerine bağımsız değişkenler atamak için, sınıf adından sonra parantez içine değerler koyun:

>>> casper = Kopek("Casper", 1)
>>> pamuk = Kopek("Pamuk", 5)

Böylece, Casper adlı 1 yaşında bir köpek ve Pamuk adlı 5 yaşındaki başka bir köpek olmak üzere iki yeni Köpek örneği oluşturmuş olursunuz.

Kopek sınıfındaki .__init__() yönteminin, üç parametresi vardır, öyleyse neden örnekte yalnızca iki argüman aktarılıyor?

Bir Kopeknesnesini başlattığınızda, Python yeni bir örnek oluşturur ve bunu .__init__()öğesinin ilk parametresine aktarır. Bu aslında self parametresini kaldırır. Bu nedenle yalnızca isimve isim parametreleri hakkında düşünmeniz gerekir.

Kopek örneklerini oluşturduktan sonra, nokta notasyonunu kullanarak bunların örnek niteliklerine erişebilirsiniz:

>>> casper.isim
'Casper'
>>> casper.yas
1

>>> pamuk.isim
'Pamuk'
>>> pamuk.yas
5

Sınıf özelliklerine aynı şekilde erişebilirsiniz:

>>> caspe.species
'Köpek familyası'

Verileri düzenlemek için sınıfları kullanmanın en büyük avantajlarından biri, örneklerin beklediğiniz özniteliklere sahip olmasının garantili olmasıdır. Tüm Kopek örneklerinin .species, .isim ve .yas nitelikleri vardır, bu nedenle bu nitelikleri her zaman bir değer döndüreceklerini bilerek içiniz rahat bir şekilde kullanabilirsiniz.

Özniteliklerin varlığı garanti edilse de, değerleri dinamik olarak değiştirilebilir:

>>> casper.yas = 6
>>> casper.yas
6

Burada gördüğünüz gibi Casper'ın yaşını kolay bir şekilde 6 olarak değiştirebildik.

Buradaki ana fikir, özel nesnelerin varsayılan olarak değiştirilebilir olmasıdır. Örneğin, listeler ve sözlükler zamanla değişebilir. Dinamik olarak değiştirme fikri çoğu zaman pratik ve kolay bir yol sunar.

Örnek Yöntemi

Örnek yöntemleri, bir sınıf içinde tanımlanan ve yalnızca o sınıfın bir örneğinden çağrılabilen işlevlerdir. Bir örnek yönteminin ilk parametresi her zaman self'dir. (.__init__() gibi)

Kullandığınız IDLE'de yeni bir düzenleyici penceresi açın ve aşağıdaki Kopek sınıfını yazın:

class Kopek:
    species = "Köpek familyası"

    def __init__(self, isim, yas):
        self.isim = isim
        self.yas = yas

    # Örnek Yöntemi
    def description(self):
        return f"{self.isim} isimli köpek {self.yas} yaşında!"

    # Diğer Örnek Yöntemi
    def speak(self, ses):
        return f"{self.isim} isimli köpek, {sound} sesi çıkarıyor!"

Bu Kopek sınıfının iki örnek yöntemi vardır:

  1. .description(), köpeğin adını ve yaşını gösteren bir dize döndürür.
  2. .speak() adlı parametre, köpeğin adını ve köpeğin çıkardığı sesi içeren bir dize döndürür.

Değiştirilen Kopek sınıfını kopek.py adlı bir dosyaya kaydedin ve programı çalıştırmak için F5'e basın. Ardından etkileşimli pencereyi açın ve örnek yöntemlerinizi çalışırken görmek için aşağıdakileri yazın:

>>> pamuk= Kopek("Pamuk", 5)

>>> pamuk.description()
'Pamuk isimli köpek 5 yaşında!'

>>> pamuk.speak("Hav Hav")
'Pamuk isimli köpek, Hav Hav sesi çıkarıyor!'

Yukarıdaki Kopeksınıfında, .description(), Kopekörneği "pamuk" hakkında, bilgi içeren bir dize döndürür. Kendi sınıflarınızı yazarken, sınıfın örneği hakkında yararlı bilgiler içeren ve bir dize döndüren yönteme sahip olmak iyi bir fikirdir. Ancak .description(), bunu yapmanın en iyi yolu değildir.

>>> names = ["Ayse", "Fatma", "Deniz"]
>>> print(names)
['Ayse', 'Fatma', 'Deniz']

Pamuk nesnesini yazdırdığınızda ne olacağını görelim:

>>> print(pamuk)
<__main__.Kopek object at 0x00aeff70>

Bunu yazdırdığınızda, 0x00aeff70 hafıza adresinde Pamuk'un bir Kopeknesnesi olduğunu söyleyen şifreli görünümlü bir mesaj alırsınız. Bu mesaj size pek yardımcı olmaz. Bunun için .__str__() adında özel bir örnek yöntemi tanımlayarak neyin yazdırılacağını değiştirebilirsiniz.

Düzenleyici penceresinde, Kopek sınıfının .description() yönteminin adını, .__str__() olarak değiştirin:

class Kopek:
    # Köpek sınıfının diğer bölümlerini olduğu gibi bırakın
    def __str__(self):
        return f"{self.isim} isimli köpek {self.yas} yaşında!"

Şimdi bu kod parçacığını kaydedip F5'e basın. Artık çok daha kolay bir çıktı elde etmiş olacaksınız:

>>> pamuk = Kopek("Pamuk", 5)
>>> print(pamuk)
'Pamuk isimli köpek 5 yaşında!'

.__init__() ve .__str__() gibi yöntemler, çift alt çizgi ile başlayıp bittiği için dunder yöntemi olarak adlandırılır. Python'da sınıfları özelleştirmek için kullanabileceğiniz birçok dunder yöntemi vardır. Bir Python eğitimi için çok ileri bir konu olmasına rağmen, dunder yöntemlerini anlamak, Python'da nesne yönelimli programlamaya hakim olmanın önemli bir parçasıdır.

Python'daki Diğer Sınıflardan Devralmak

Devralmak ve miras sistemi, bir sınıfın diğerinin niteliklerini ve yöntemlerini üstlendiği süreçtir. Yeni oluşturulmuş sınıflara alt sınıflar denir ve alt sınıfların türetildiği sınıflara ebeveyn sınıfları denir.

Alt sınıflar, üst sınıfların özniteliklerini ve yöntemlerini geçersiz kılabilir veya genişletebilir. Diğer bir deyişle, alt sınıflar ebeveynin tüm özniteliklerini ve yöntemlerini miras alır, ancak kendilerine özgü öznitelikleri ve yöntemleri de belirleyebilir.

Nesne mirasını bir tür genetik kalıtım gibi düşünebilirsiniz.

Saç renginizi annenizden almış olabilirsiniz. Bu doğduğunuz bir niteliktir. Diyelim ki saçınızı mora boyamaya karar verdiniz. Annenizin mor saçı olmadığını varsayarsak, annenizden miras aldığınız saç rengi özelliğini geçersiz kıldınız.

Dilinizi bir anlamda anne babanızdan da miras alırsınız. Ebeveynleriniz İngilizce konuşuyorsa, o zaman İngilizce konuşursunuz. Şimdi Almanca gibi ikinci bir dil öğrenmeye karar verdiğinizi hayal edin. Bu durumda , ebeveynlerinizin sahip olmadığı bir özellik eklediğiniz için niteliklerinizi genişletmiş olacaksınız.

Köpek Parkı Örneği

Bir an için köpek parkında olduğunuzu hayal edin. Parkta, çeşitli köpek davranışları sergileyen, farklı ırklardan birçok köpek olacaktır.

Şimdi köpek parkını Python sınıflarıyla modellemek istediğinizi varsayalım. Önceki bölümde yazdığınız Kopek sınıfı, köpekleri isme ve yaşa göre ayırt edebilir, ancak cinse göre ayırt edemez.

Bir .breed niteliği ekleyerek editör penceresinde Kopek sınıfını değiştirebilirsiniz:

class Kopek:
    species = "Köpek familyası"

    def __init__(self, isim, yas, breed):
        self.isim = isim
        self.yas = yas
        self.breed = breed

Daha önce tanımlanan örnek yöntemler, bu başlık altında önemli olmadıklarından dolayı burada atlanmıştır.

Dosyayı kaydetmek için F5'e basın. Artık etkileşimli pencerenizde bir grup farklı köpeği örnekleyerek köpek parkını modelleyebilirsiniz:

>>> pamuk = Kopek("Pamuk", 5, "Jack Russell Terrier")
>>> casper = Kopek("Casper", 1, "Pug")
>>> hector = Koper("Hector", 3, "Bulldog")
>>> pasa = Kopek("Pasa", 4, "Labrador")

Her köpek cinsinin biraz farklı davranışları vardır. Havlama sesleri bile aynı değildir.

Sadece Kopek sınıfını kullanarak, bir Kopek örneğinde, her çağırdığınızda .speak() ses argümanı için bir dize sağlamalısınız:

>>> casper.speak("HEV")
'Casper isimli köpek, HEV sesi çıkarıyor!'

>>> pasa.speak("HOV")
'Pasa isimli köpek, HOV sesi çıkarıyor!'

>>> hector.speak("HAV")
'Hector isimli köpek, HAV sesi çıkarıyor!'

.speak()'e yapılan her çağrıya bir dize iletmek tekrarlayıcı ve zahmetli bir işlemdir. Dahası, her bir Kopek örneğinin çıkardığı sesi temsil eden dize, .breed özelliğine göre belirlenmelidir, ancak burada her çağrıldığında doğru dizeyi .speak() 'e manuel olarak iletmeniz gerekir.

Her köpek türü için bir child sınıfı oluşturarak Kopek sınıfı ile çalışma deneyimini basitleştirebilirsiniz. Bu, .speak() için varsayılan bir bağımsız değişken belirtmek de dahil olmak üzere, her bir alt sınıfın miras aldığı işlevselliği genişletmenize olanak tanır.

Ebeveyn Sınıflar ve Alt (Child) Sınıflar

Burada bahsedilen üç ırkın her biri için bir child sınıf oluşturalım: Bulldog, Pug, Labrador.

class Kopek:
    species = "Köpek familyası"

    def __init__(self, isim, yas):
        self.isim = isim
        self.yas = yas

    def __str__(self):
        return f"{self.isim} isimli köpek, {self.yas} yaşında!"

    def speak(self, sound):
        return f"{self.isim} isimli köpek, {sound} sesi çıkarır!"

Unutmayın, bir alt sınıf (child sınıf) oluşturmak için kendi adıyla yeni bir sınıf oluşturursunuz ve ardından ana sınıfın adını parantez içine alırsınız. Kopeksınıfının üç yeni alt sınıfını oluşturmak için kopek.py dosyasına aşağıdakileri ekleyin:

class Bulldog(Kopek):
    pass

class Pug(Kopek):
    pass

class Labrador(Kopek):
    pass

Dosyayı kaydetmek ve çalıştırmak için F5'e basın.

>>> pamuk = JackRussellTerrier("panuk", 5)
>>> casper = Pug("Casper", 1)
>>> Pasa = Labrador("Pasa", 4)
>>> Hector = Bulldog("Hector", 3)

Alt sınıfların örnekleri, üst sınıfın tüm özniteliklerini ve yöntemlerini devralır:

>>> pamuk.species
'Köpek familyası'

>>> casper.name
'Casper'

>>> print(casper)
Casper isimli köpek 1 yaşında!

>>> hector.speak("HAV")
'Hector isimli köpek, HAV sesi çıkarır!'

Belirli bir nesnenin hangi sınıfa ait olduğunu belirlemek için type() kullanabilirsiniz:

>>> type(pamuk)
<class '__main__.JackRussellTerrier'>

Peki ya "Pamuk" nesnesinin Kopek sınıfının bir örneği olup olmadığını belirlemek istiyorsanız? İşte bunu yerleşik isinstance() ile yapabilirsiniz:

>>> isinstance(pamuk, Kopek)
True

Yukarıdaki örnekte, isinstance (), pamuk nesnesinin Kopeksınıfının bir örneği olup olmadığını kontrol eder ve True döndürür.

isinstance() 'in iki argüman, bir nesne ve bir sınıf aldığına dikkat edin.

>>> isinstance(pamuk, Bulldog)
False

>>> isinstance(casper, Labrador)
False

Daha genel olarak, bir alt sınıftan oluşturulan tüm nesneler, diğer alt sınıfların örnekleri olmasa da, ana sınıfın örnekleridir.

Bir Üst Sınıfın İşlevselliğini Genişletin

Üst sınıfta tanımlanan bir yöntemi geçersiz kılmak için, alt sınıfta aynı ada sahip bir yöntem tanımlarsınız. Bunu JackRussellTerrier sınıfı için yapmak istersek şu şekilde görünecektir:

class JackRussellTerrier(Kopek):
    def speak(self, sound="HEV"):
        return f"{self.isim} isimli köpek, {sound} sesi çıkarır!"

Artık .speak(), ses için varsayılan bağımsız değişken "HEV" olarak ayarlanmış ve JackRussellTerrier sınıfında tanımlanmıştır.

kopek.py'yi yeni JackRussellTerrier sınıfıyla güncelleyin ve dosyayı kaydedip çalıştırmak için F5'e basın. Artık bir JackRussellTerrier örneğinde ..speak() 'i ses için bir bağımsız değişken iletmeden çağırabilirsiniz:

>>> pamuk = JackRussellTerrier("Pamuk", 5)
>>> pamuk.speak()
'Pamuk isimli köpek HEV sesi çıkarır!'

Bazen köpekler duygu durumlarına göre farklı sesler çıkarır, bu nedenle Pamuk eğer kızar ve hırlarsa, farklı bir sesle .speak() öğesini yine de arayabilirsiniz:

>>> pamuk.speak("Hrrr")
'Pamuk isimli köpek, Hrrr sesi çıkarır!'

Sınıf mirası hakkında akılda tutulması gereken bir şey, ana sınıftaki değişikliklerin otomatik olarak alt sınıflara yayılmasıdır. Bu, değiştirilen öznitelik veya yöntem, alt sınıfta geçersiz kılınmadığı sürece gerçekleşir.

Örneğin, düzenleyici penceresinde, Kopek sınıfında .speak() tarafından döndürülen dizeyi değiştirin:

    # Diğer öznitelikleri ve yöntemleri olduğu gibi bırakın
    def speak(self, sound):
        return f"{self.isim} şu şekilde havlar: {sound}"

Dosyayı kaydedin ve F5 tuşuna basın. Şimdi, hector adında yeni bir Bulldog örneği oluşturduğunuzda, hector.speak() yeni dizeyi döndürecektir:

>>> hector = Bulldog("Hector", 3)
>>> hector.speak("Hoof")
'Hector şu şekilde havlar: Hoof'

Ancak, bir JackRussellTerrier örneğinde, .speak() 'i çağırmak yeni çıktı stilini göstermez:

>>> pamuk = JackRussellTerrier("Pamuk", 5)
>>> pamuk.speak()
'Pamuk isimli köpek HEV sesi çıkarır!'

Bazen ana sınıftan bir yöntemi tamamen geçersiz kılmak mantıklı olabilir. Ancak bu örnekte JackRussellTerrier sınıfının, kopek.speak() çıkış dizesinin biçimlendirmesinde yapılabilecek herhangi bir değişikliği kaybetmesini istemiyoruz.

Bunu yapmak için, JackRussellTerrier alt sınıfında bir .speak() yöntemi tanımlamanız gerekir. Ancak çıktı dizesini açıkça tanımlamak yerine, JackRussellTerrier.speak() 'e ilettiğiniz aynı argümanları kullanarak alt sınıfın .speak() içindeki Kopek sınıfının .speak() öğesini çağırmanız gerekir.

Bunun için, super() kullanarak alt sınıfın bir yönteminin içinden üst sınıfa erişebilirsiniz:

class JackRussellTerrier(Kopek):
    def speak(self, sound="HEV"):
        return super().speak(sound)

JackRussellTerrier içindeki super() ile speak(sound)'u çağırdığınızda, Python, Kopek ana sınıfında .speak() yöntemini arar ve onu değişken sesle çağırır.

kopek.py'yi yeni JackRussellTerrier sınıfıyla güncelleyin. Dosyayı kaydedin ve etkileşimli pencerede test edebilmek için F5 tuşuna basın:


>>> pamuk = JackRussellTerrier("Pamuk", 5)
>>> pamuk.speak()
'Pamuk şu şekilde havlar: HEV'

Artık pamuk.speak() öğesini çağırdığınızda, Kopek sınıfındaki yeni biçimlendirmeyi yansıtan çıktıyı görebilirsiniz.

Not: Yukarıdaki örneklerde, sınıf hiyerarşisi çok basittir. JackRussellTerrier sınıfının tek bir ebeveyn sınıfı vardır. Örneğimizde bu ebeveyn sınıf elbette ki, Kopek. Gerçek dünya örneklerinde, sınıf hiyerarşisi oldukça karmaşık hale gelebilir.

super(), bir yöntem veya öznitelik için üst sınıfta arama yapmaktan çok daha fazlasını yapar. Eşleşen bir yöntem veya öznitelik için tüm sınıf hiyerarşisini dolaşır.

Özetlemek Gerekirse

Bu makalede, Python'da nesne yönelimli programlama (OOP) hakkında bilgi edinmiş oldunuz. Java, C# ve C++ gibi çoğu modern programlama dili OOP ilkelerini takip eder, bu nedenle burada edindiğiniz bilgiler programlama kariyeriniz sizi nereye götürürse götürsün uygulanabilir olacaktır.

Peki neler öğrendik?

  1. Belirli bir nesne için, bir tür taslak olan basit bir sınıf tanımlamak
  2. Bir sınıftan bir nesneyi örneklemek
  3. Bir nesnenin özelliklerini ve davranışlarını tanımlamak için nitelikleri ve yöntemleri kullanmak
  4. Bir üst sınıftan alt sınıflar oluşturmak için miras sistemini kullanmak
  5. super() kullanarak üst sınıfta bir yönteme başvurmak
  6. Bir nesnenin isinstance() kullanarak başka bir sınıftan miras alıp almadığını kontrol etmek

Python zevkli, öğrenmesi eğlenceli bir dildir. Nesne yönelimli programlama konusunda ve öğrendiğiniz diğer dil, teknoloji, geliştirme aracı konularında sizlere başarılar diliyorum.

Mutlu Kodlamalar.

Sağlıcakla Kalın!

Anatoliacode Makale Aboneliği

Bize abone olarak tüm makaleleri ilk siz okuyabilirsiniz. Ayrıca asla reklam veya spam yapmıyoruz.