#!/usr/bin/env python # coding: utf-8 # # Nesne Tabanlı Programlama - Kalıtım (Inheritance) # Bu konuda **Nesne Tabanlı Programlamadaki** inheritance(kalıtım veya miras alma) konseptini öğrenmeye çalışacağız. Inheritance veya kalıtım bir sınıfın başka bir sınıftan özelliklerini(**attribute** ) ve metodlarını miras almasıdır. # # # Bu konsepti aslında bizim kendi anne babamızdan değişik özellikleri ve davranışları miras almamıza benzetebiliriz.(Hani derler ya ! Babasına çekmiş :) ) # # Peki inheritance nerede işimize yarar ? Örneğin, bir şirketin çalışanlarını tasarlamak için sınıflar oluşturuyoruz. Bunun için Yönetici, Proje Direktörü, İşçi gibi sınıflar oluşturmamız gerekiyor. Aslında baktığımız zaman bu sınıfların hepsinin belli ortak metodları ve özellikleri bulunuyor. O zaman bu ortak özellikleri ve metodları tekrar tekrar bu sınıfların içinde tanımlamak yerine, bir tane ana class tanımlayıp bu classların bu classın özelliklerini ve metodlarını almalarını sağlayabiliriz. **Inheritance'ın veya Kalıtım'ın** temel mantığı budur. # # İsterseniz inheritance yapısını kurmak için öncelikle bir tane çalışan sınıfı oluşturalım. # # In[63]: class Çalışan(): def __init__(self,isim,maaş,departman): print("Çalışan sınıfının init fonksiyonu") self.isim = isim self.maaş = maaş self.departman = departman def bilgilerigoster(self): print("Çalışan sınıfının bilgileri.....") print("İsim : {} \nMaaş: {} \nDepartman: {}\n".format(self.isim,self.maaş,self.departman)) def departman_degistir(self,yeni_departman): print("Departman değişiyor....") self.departman = yeni_departman # Çalışan sınıfını oluşturduk şimdi de Yönetici sınıfını bu Çalışan sınıfından türetmeye çalışalım. # In[64]: class Yönetici(Çalışan): # Çalışan sınıfından miras alıyoruz. pass # Pass Deyimi bir bloğu sonradan tanımlamak istediğimizde kullanılan bir deyimdir. # Burada, yönetici sınıfında herhangi bir şey tanımlamadık ancak Çalışan sınıfından bütün özellikleri ve metodları miras aldık. Bakalım burada Çalışan sınıfının metodlarını kullanabilecek miyiz ? # In[65]: yönetici1 = Yönetici("Mehmet Baltacı",3000,"İnsan Kaynakları") # yönetici objesi # In[66]: yönetici1.bilgilerigoster() # In[67]: yönetici1.departman_degistir("Halkla İlişkiler") # In[68]: yönetici1.bilgilerigoster() # Burada gördüğümüz gibi bütün özellikleri ve metodları Çalışan sınıfından miras aldığımız için kullanabiliyoruz. Bunu ***dir()*** fonksiyonu ile de görebiliriz. # In[69]: dir(yönetici1) # Peki biz Yönetici sınıfına ekstra fonksiyonlar ve özellikler ekleyebiliyor muyuz ? Örnek olması açısından **zam_yap** isimli bir metod ekleyelim. # In[73]: class Yönetici(Çalışan): def zam_yap(self,zam_miktarı): print("Maaşa zam yapılıyor....") self.maaş += zam_miktarı # In[74]: yönetici2 = Yönetici("Mustafa Murat Coşkun",3000,"Bilişim") # yönetici objesi # In[75]: yönetici2.bilgilerigoster() # In[76]: yönetici2.zam_yap(500) # Ekstra eklediğimiz fonksiyonu da kullanabiliyoruz. # In[77]: yönetici2.bilgilerigoster() # İşte biz bir sınıftan miras alarak oluşturduğumuz sınıflara ekstra metodlar ve özellikler de ekleyebiliyoruz. # ### Overriding (İptal Etme) # # Eğer biz miras aldığımız metodları **aynı isimle** kendi sınıfımızda tekrar tanımlarsak , artık metodu çağırdığımız zaman **miras aldığımız değil kendi metodumuz çalışacaktır.** Buna Nesne Tabanlı Programlamada bir metodu override etmek denmektedir. # # Örneğin artık Çalışan sınıfının **init** metodunu kullanmak yerine Yönetici sınıfında **init** metodunu override edebiliriz. Böylelikle Yönetici sınıfına ekstra özellikler(**attribute**) ekleyebiliriz. # In[3]: class Çalışan(): def __init__(self,isim,maaş,departman): print("Çalışan sınıfının init fonksiyonu") self.isim = isim self.maaş = maaş self.departman = departman def bilgilerigoster(self): print("Çalışan sınıfının bilgileri.....") print("İsim : {} \nMaaş: {} \nDepartman: {}\n".format(self.isim,self.maaş,self.departman)) def departman_degistir(self,yeni_departman): print("Departman değişiyor....") self.departman = yeni_departman # In[4]: class Yönetici(Çalışan): def __init__(self,isim,maaş,departman,kişi_sayısı): # Sorumlu olduğu kişi sayısı print("Yönetici sınıfının init fonksiyonu") self.isim = isim self.maaş = maaş self.departman = departman self.kişi_sayısı = kişi_sayısı # Yeni eklenen özellik def zam_yap(self,zam_miktarı): print("Maaşa zam yapılıyor....") self.maaş += zam_miktarı # In[5]: a = Yönetici("Mustafa Murat Coşkun",3000,"Bilişim",10) # Yönetici sınıfının init fonksiyonu. Override edildi. # İsterseniz şimdi de **bilgilerigoster** metodunu override edelim. # In[86]: class Çalışan(): def __init__(self,isim,maaş,departman): print("Çalışan sınıfının init fonksiyonu") self.isim = isim self.maaş = maaş self.departman = departman def bilgilerigoster(self): print("Çalışan sınıfının bilgileri.....") print("İsim : {} \nMaaş: {} \nDepartman: {}\n".format(self.isim,self.maaş,self.departman)) def departman_degistir(self,yeni_departman): print("Departman değişiyor....") self.departman = yeni_departman # In[90]: class Yönetici(Çalışan): def __init__(self,isim,maaş,departman,kişi_sayısı): # Sorumlu olduğu kişi sayısı print("Yönetici sınıfının init fonksiyonu") self.isim = isim self.maaş = maaş self.departman = departman self.kişi_sayısı = kişi_sayısı # Yeni eklenen özellik def bilgilerigoster(self): print("Yönetici sınıfının bilgileri.....") print("İsim : {} \nMaaş: {} \nDepartman: {}\nSorumlu kişi sayısı: {}".format(self.isim,self.maaş,self.departman,self.kişi_sayısı)) def zam_yap(self,zam_miktarı): print("Maaşa zam yapılıyor....") self.maaş += zam_miktarı # In[91]: b = Yönetici("Serhat Say",2500,"Pazarlama",5) # In[93]: b.bilgilerigoster() # Kendi yazdığımız fonksiyon çağrıldı. Overriding # ### super Anahtar Kelimesi # **super** anahtar kelimesi özellikle override ettiğimiz bir metodun içinde aynı zamanda miras aldığımız bir metodu kullanmak istersek kullanılabilir. Yani **super** en genel anlamıyla miras aldığımız sınıfın metodlarını alt sınıflardan kullanmamızı sağlar. Hemen örnek üzerinden anlamaya çalışalım. # In[99]: class Çalışan(): def __init__(self,isim,maaş,departman): print("Çalışan sınıfının init fonksiyonu") self.isim = isim self.maaş = maaş self.departman = departman def bilgilerigoster(self): print("Çalışan sınıfının bilgileri.....") print("İsim : {} \nMaaş: {} \nDepartman: {}\n".format(self.isim,self.maaş,self.departman)) def departman_degistir(self,yeni_departman): print("Departman değişiyor....") self.departman = yeni_departman # In[100]: class Yönetici(Çalışan): def __init__(self,isim,maaş,departman,kişi_sayısı): # Sorumlu olduğu kişi sayısı super().__init__(isim,maaş,departman) # 3 tane özelliği Çalışan fonksiyonunun init fonksiyonuyla hallediyoruz. print("Yönetici sınıfının init fonksiyonu") self.kişi_sayısı = kişi_sayısı # Ekstra özelliği de kendimiz yazıyoruz. def bilgilerigoster(self): print("Yönetici sınıfının bilgileri.....") print("İsim : {} \nMaaş: {} \nDepartman: {}\nSorumlu kişi sayısı: {}".format(self.isim,self.maaş,self.departman,self.kişi_sayısı)) def zam_yap(self,zam_miktarı): print("Maaşa zam yapılıyor....") self.maaş += zam_miktarı # Burada **super().__init()** diyerek Çalışan sınıfının metodunu **özel olarak çağırarak** isim, maaş , departman özelliklerini bu metodla belirledik. # In[101]: c = Yönetici("Oğuz Artıran",3000,"İnsan Kaynakları",4) # # İşte inheritance konusu bu kadar ! İlk başlarda karışık gelmiş gibi görünebilir. Ancak bu yapıları kullana kullana alışacaksınız. # In[ ]: