Kalıtım ve çok biçimlilik: devralma ve aynı çağrı, farklı davranış
Sözlük

Kalıtım ve çok biçimlilik: devralma ve aynı çağrı, farklı davranış

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 4 dk okuma

Kalıtım ortak davranışı üst sınıftan devralır, çok biçimlilik aynı çağrının farklı sınıflarda farklı çalışmasını sağlar. Python örneğiyle farkları görün.

Kalıtım nedir?

Kalıtım (inheritance), bir sınıfın başka bir sınıfın özelliklerini ve metotlarını devralmasıdır. Devralan sınıfa alt sınıf (child), devralınan sınıfa üst sınıf (parent) denir. Alt sınıf, üst sınıftaki ortak davranışı yeniden yazmadan kullanır; üstüne kendine özgü davranış ekleyebilir.

Kalıtımın dayandığı düşünce "bir türdür" ilişkisidir. Kedi bir hayvandır, kredi kartı bir ödeme yöntemidir. Bu cümle doğal biçimde kurulabiliyorsa kalıtım uygun olabilir. "Araba, motora sahiptir" gibi bir ilişkiyi kalıtımla değil, bir nesnenin başka bir nesneyi içermesi yani kompozisyonla kurmak gerekir.

Çok biçimlilik nedir?

Çok biçimlilik (polymorphism), aynı çağrının nesnenin gerçek türüne göre farklı davranmasıdır. Çağıran kod, karşısındaki nesnenin tam olarak hangi sınıfa ait olduğunu bilmek zorunda değildir; yalnızca ortak bir arayüzü kullanır.

Örneğin bir ödeme sisteminde kredi kartı, havale ve cüzdan ödemelerinin her birinde "öde" çağrısı yapılır. Her sınıf bu çağrıyı kendi yöntemiyle gerçekleştirir. Ödeme akışını yazan geliştirici yeni bir yöntem eklendiğinde mevcut kodu değiştirmek zorunda kalmaz; yalnızca yeni bir sınıf tanımlanır.

Python'da bir örnek

Şu kod kalıtımı ve çok biçimliliği bir arada gösterir:

class Odeme: def ode(self, tutar): raise NotImplementedError

class KrediKarti(Odeme): def ode(self, tutar): return "kart ile ödendi"

class Havale(Odeme): def ode(self, tutar): return "havale ile ödendi"

for yontem in [KrediKarti(), Havale()]: print(yontem.ode(tutar))

KrediKarti ve Havale, Odeme sınıfını devralır; bu kalıtımdır. Döngüdeki aynı ode çağrısı her nesnede farklı sonuç üretir; bu da çok biçimliliktir. Alt sınıfın üst sınıftaki bir metodu kendi sürümüyle değiştirmesine metot ezme (method overriding) denir. Üst sınıfın davranışını korurken genişletmek için super() çağrısı kullanılır.

Kalıtım ile çok biçimlilik arasındaki ilişki

Kalıtım, kodun yeniden kullanımını ve türler arası ilişkiyi sağlar. Çok biçimlilik ise bu ilişkinin getirdiği esnekliktir: ortak bir üst tür sayesinde farklı alt türler aynı arayüzle kullanılabilir. Çok biçimlilik kalıtım olmadan da mümkündür. Python'da bir nesnenin gerekli metoda sahip olması yeterlidir; buna ördek tipleme (duck typing) denir. Java ve C# gibi dillerde ise çok biçimlilik genellikle ortak bir arayüz ya da üst sınıf üzerinden kurulur.

Karıştırılan bir başka kavram aşırı yükleme (overloading) ile ezme (overriding) arasındaki farktır. Aşırı yükleme aynı adlı metodun farklı parametre listeleriyle tanımlanmasıdır ve bazı dillerde desteklenir. Ezme ise alt sınıfın üst sınıf metodunu aynı imzayla yeniden yazmasıdır; çalışma anındaki çok biçimliliği bu sağlar.

Kalıtımın riskleri ve kompozisyon

Kalıtım güçlü ama sıkı bir bağ kurar: üst sınıf değiştiğinde tüm alt sınıflar etkilenir. Derin hiyerarşilerde bir değişikliğin nereleri bozacağını kestirmek zorlaşır. Bu nedenle "kalıtım yerine kompozisyonu tercih et" ilkesi yaygın bir tasarım önerisidir.

Kalıtım kullanılacaksa Liskov ikame ilkesine dikkat edilir: alt sınıf nesnesi, üst sınıf nesnesinin kullanıldığı her yerde beklenmedik hata üretmeden kullanılabilmelidir. Örneğin kuş sınıfından türeyen ve uçamayan bir penguen sınıfı, "uç" metodunu hata ile cevaplıyorsa bu ilkeyi bozar. Çoklu kalıtımı destekleyen dillerde (Python gibi) aynı metodun birden fazla üst sınıfta bulunması çözüm sırası (MRO) kurallarıyla yönetilir.

Soyut sınıf ve arayüz

Soyut sınıf, doğrudan nesnesi üretilmeyen ve alt sınıflara şablon sunan sınıftır. Bazı metotları gövdesiz bırakıp alt sınıfın doldurmasını zorunlu kılabilir. Arayüz (interface) ise bir sınıfın uyması gereken metot listesini tanımlayan sözleşmedir. Python'da bu rolü soyut temel sınıflar üstlenir.

Bu yapılar çok biçimliliğin güvenli kurulmasını sağlar: alt sınıf gerekli metodu yazmadıysa program daha çalışmadan hata verir. Bağımlılık tersine çevirme gibi SOLID ilkeleri de soyutlamalara bağlı kalmayı önerir, çünkü yüksek seviyeli kod somut sınıflara değil arayüzlere bağlıysa değiştirilmesi kolaylaşır.

Mindset programlarında nerede çalışılır?

Python ile Nesne Yönelimli Programlama programının kalıtım, kompozisyon ve çözüm sırası modülü, bu kavramları Python üzerinde uygulamalı olarak işler. Sınıf hiyerarşilerini tasarlamakta zorlanan ya da miras alınan karmaşık bir kod tabanını anlamaya çalışan geliştiriciler için uygundur.

SOLID Prensipleri ve Nesne Yönelimli Tasarım programı ise Liskov ikame ve arayüz ayrıştırma başlıklarıyla alt sınıfların güvenli kurulmasını kapsar. Kod inceleme sırasında hiyerarşi kararlarını tartışacak ekipler için ortak bir ölçüt sağlar.

İlgili Mindset programı

Python ile Nesne Yönelimli Programlama

Sık sorulanlar

Sık sorulan sorular

Kalıtım mı kompozisyon mu kullanmalıyım?

Kural olarak "bir türdür" ilişkisi açıkça kuruluyorsa ve alt sınıf üst sınıfın her davranışını sorunsuz devralıyorsa kalıtım uygundur. Aksi halde, yani "sahiptir" ilişkisinde ya da davranışı çalışma anında değiştirmek gerektiğinde kompozisyon daha esnek ve bakımı daha kolaydır.

Polimorfizm ile metot ezme aynı şey mi?

Aynı değildir ama yakından ilişkilidir. Metot ezme, alt sınıfın üst sınıf metodunu kendi sürümüyle değiştirmesidir. Polimorfizm ise bu ezmenin çalışma anında doğru sürümün seçilmesini sağlayan sonucudur. Ezme bir mekanizma, polimorfizm ise o mekanizmanın sağladığı davranış esnekliğidir.

Python'da çok biçimlilik için kalıtım şart mı?

Hayır. Python ördek tiplemeyi destekler: bir nesne gereken metoda sahipse, hangi sınıftan türediğine bakılmadan kullanılır. Yine de büyük ekiplerde ortak bir soyut temel sınıf, beklenen arayüzü açıkça belgeler ve eksik metot yazılırsa hatayı erken yakalar.

Çoklu kalıtım neden tartışmalıdır?

Bir sınıf birden fazla üst sınıftan türediğinde aynı adlı metodun hangisinden geleceği belirsizleşebilir. Python bunu çözüm sırası kurallarıyla çözer; bazı diller çoklu kalıtımı hiç sunmaz ve yerine arayüzleri kullanır. Çoklu kalıtım dikkatli kullanılmazsa kodun izlenmesini zorlaştırır.

Kalıtım ve Çok Biçimlilik Nedir? Örnekle Açıklama