26
Oca'14

OOP 7: Kalıtım (Inheritance) (C# ile OOP)

Nesneye yönelik programlamanın yapıtaşlarından biri de kalıtımdır. Kalıtım kelimesi yerine bazen miras alma ya da ingilizcesi olan inheritance kullanılabilir.

 

OOP için kalıtım, bir sınıfın başka bir sınıftan türetilmesidir. Bazı programlama dilleri için bir sınıfın başka bir ya da birkaç sınıftan türetilmesi de mümkün iken c# için bir sınıf sadece başka bir adet sınıftan türetilebilir. Kısaca c# çoklu kalıtıma(multiple inheritance) izin vermiyor.

kalitim0

C# ‘ta kalıtım, adımımızı attığımız her yerdedir:) Nasıl mı? Daha önceki yazılarımdan birinde bahsettiğim gibi; c#’ta her şey object sınıfından kalıtılmıştır. Bir önceki paragrafta dediğimden yola çıkarak, her sınıf sadece bir sınıftan kalıtılıyorsa ve zaten object sınıfından kalıtıldıysa, nasıl bir sınıfı kendi istediğimiz diğer bir sınıftan kalıtacağız? Tabiki böyle bir karmaşa yok. Eğer biz bir sınıfın hangi sınıftan kalıtılacağını belirtmediysek, object sınıfından kalıtılır.

Neden Kalıtıma İhtiyaç Duyulur?

Doğayı nasıl anlamlandırırız? Beynimizde doğadaki canlılar nasıl yer tutar? Özelden genele canlıları nasıl sınıflandırdığımızı görebiliyor muyuz? Tanımlamamız bir köpek olsa da bu tanımın, bir sınıflandırmanın içinde olduğunu biliyoruz. Varlık->canlı->memeli->köpek… Örneğin, kedi ve köpeğin ortak noktası memeliler sınıfından olmak, koşabilmeleri ortak özellikleri. Bu ve bunun gibi ayrımları, genelden özele anlamlandırmaları yapabilme yeteneğine insanoğlu zaten sahip. Yazılıma da bu anlamlandırma yeteneği kalıtım ile kazandırılmaktadır.

 

Kalıtım sayesinde, bir üst sınıftan türetilmiş sınıflar, üst sınıfın istenilen özelliklerini kendilerine alırlar. Bu sayede:

 

– Gereksiz kod yazımından bir nebze olsun kurtulmuş oluruz.

– Kodun anlaşılması daha kolay olur.

– Yazılıma harcanan zaman azalır.(Uzun soluklu projeler için.)

– Sonradan gelebilecek değişikliklere kolay uyum sağlayabilecek esnek kodlar yazılmış olur.

– Sistemin, ek ihtiyaçların kolay entegre olabilmesi mümkün olur.

 

Yukarıdaki maddeler OOP yaklaşımının sağladığı faydalardır aynı zamanda. Tabiki bunlar kalıtımın doğru şekilde uygulanmasıyla mümkündür. Peki kalıtım nasıl uygulanır? Örnek kodlarla beraber bu konuya açıklık getirmeye çalışalım.

Kalıtımın Uygulanması

Birkaç farklı türde taşıtı satabilen bir oto galeri için uygulama yazdığımızı düşünelim. Farklı taşıt türleri için farklı fiyat belirleme ihtiyacı doğacaktır. Biz de her taşıt türü için fiyat hesaplama fonksiyonu kodlayalım en iyisi. İhtiyacımıza göre bir tanesini çağırır fiyatını hesaplatırız. Her şey ne kadar güzel. Sonra fiyat hesaplamadaki yöntem değiştiğinde gidip her fonksiyonu tek tek değiştiririz. Değiştrir miyiz? İşte orda durun! Değiştirmeyin. İyisi mi kodu tamamen silin:). Hatta hiç böyle kodlamayın. Gelin biz, OOP yaklaşımı ve kalıtımı bu problem için nasıl doğru şekilde uygularız bir plan yapalım.

 

İlk önce sınıfların yapısını planlayalım. Farklı türden taşıtları içerebilecek bir taşıt sınıfı olmalı. Örneğin basit olması açısından otomobil ve kamyonet olarak iki farklı taşıt türünü ele alalım. Bu durumda aşağıdaki gibi bir yapıya ihtiyacımız var.

kalitim1

Bir sınıfı başka bir sınıftan türetmek için sınıf adının yanına “:” koyarak miras alınacak sınıfın adı yazılır.

Yukarıdaki diyagram için sınıfların kodları aşağıdaki gibidir.

class Tasit { }

class Otomobil : Tasit { }

class Kamyonet : Tasit { }

İsteğimiz, taşıtlar için fiyat hesaplayabilmekti. Bunu az kod ve esnek bir şekilde halletmek için artık fonksiyonu Tasit sınıfı içerisine kodlayabilir ve diğer sınıfların üzerinden çağırabilirz.

Tasit sınıfının son hali aşağıdaki gibidir.

class Tasit 
{
    public decimal SaatBasinaUcret { get; set; }
    public int Sure { get; set; } // Saat bazında.

    public decimal FiyatHesapla()
    {
        return SaatBasinaUcret * Sure;
    }
}

Şimdi taşıt tipinden bir otomobil belleğe çıkaralım ve property’lerini set ederek fiyatını hesaplayalım.

static void Main(string[] args)
{
    // Object initializer kullanarak property'lere değer atayalım.
    Otomobil otomobil = new Otomobil()
    {
        Sure = 5,
        SaatBasinaUcret = (decimal)5/4,
    };

    Console.WriteLine(otomobil.FiyatHesapla());
}

Aynı şekilde kamyonet sınıfı için de FiyatHesapla metodunu kullanabiliriz. Böylelikle her tip için bir fiyat hesaplama metodu yazmak yerine sadece base class’a yazarak işi tamamlamış olduk.

 

Şimdiye kadar anlatılanlara birkaç ek yapalım ve biraz toparlayalım:

 

– İlk önce kalıtımdan ve kalıtıma neden ihtiyaç duyulabileceğinden bahsettik.

– Kalıtımın uygulanması ile ilgili ufak bir örnek yaptık.

– Base class’taki public bir metodun nasıl alt sınıflardan çağırılabildiğini gördük.

– Erişim belirleyiciler konusunda anlattığım gibi, public elemanlar her yerden erişilebilir durumdadır. Eğer sadece alt sınıfların erişmesini istediğiniz bir eleman varsa protected ile işaretlemeniz gerekmektedir.

Internal protected ile işaretlenmiş elemanlara ise assembly dışından türetilmiş alt sınıflar da erişebilir.

 

– Kalıtımla birlikte değinilmesi gereken diğer konular ise, türettiğimiz sınıfların birinden nesne örneklediğimizde constructor çağırımlarının nasıl yapıldığı, base class ctor’una nasıl parametre gönderildiği, base, override, new anahtar kelimeleri olarak sıralanabilir. Bu konuyu içeren sıradaki yazıyı okumak için tıklayınız.

 

İyi Eğlenceler:)

  • Sinan Bozkuş

    Baştan sona tüm yazılarınızı okudum, gerçekten çok faydalı bilgiler paylaşmışsınız. Bağış butonu olsa bağış yapacaktım neredeyse :) Emeğinize sağlık, çok çok teşekkür ederim. Genel anlamda bildiğim konularda bilmediğim bazı ufak ama değerleri bölümleri öğrendim sayenizde.

Yeni makaleleri E-Mail ile takip edin!