Nesne Yönelimli Programlamanın (Object Oriented Programming) Felsefesini Anlamak

Nesne yönelimli olarak kodlama yapmadan önce tanışmanız gereken mantık ve kavramlar!

Tarık
Kodcular
12 min readMay 16, 2020

--

“Nesne Yönelimli Programlamanın (Object Oriented Programming) Felsefesini Anlamak” konu başlıklı makalenin başlangıç görseli.
Görsel 0. Nesne Yönelimli Programlamanın (Object Oriented Programming) Felsefesini Anlamak

Gereklilikler: Çok temel düzeyde programlama bilgisi, istek, zaman

  1. Özet
  2. Giriş
  3. Nesne Yönelimli Olmanın Özü
  4. Nesne Yönelimli Programlamanın Yapı Taşları
    4.1. Sınıf (Class) ve Nesne (Object)
    4.2. Kapsülleme (Encapsulation)
    4.3. Kalıtım (Miras) (Inheritance)
    4.4. Çok Şekillilik (Polymorphism)
  5. Sonuç

1. Özet

Programlama yaptıkça ve projeler nispeten büyüdükçe, anlaşılır ve yönetilebilir kodlamanın peşine düşüyoruz. Kendi yazdığınız kodu sonradan anlayamamak gibi bazı garip olayları da muhtemelen tecrübe etmişsinizdir. Tabii ki bu karmaşanın birden çok sebebi olabilir. Değişken isimleri, fonksiyon isimleri, … Bizim şu anki amacımız ise nesne yönelimli programlama (Object Oriented Programming) yöntemini kullanarak insan algısına yakın tasarımlar oluşturabilmek ve kodlama yapabilmek.

Kendi sınıflarımızı (Class) oluşturabilir ve buradan nesneler (Object) üretip kullanabiliriz. Tıpkı, genel bir araba tanımındaki özniteliklerle, X markasının Y model bir arabayı üretmesi gibi.

Bu sınıflarda bulunan verileri koruyabilmek ve bazı kriterlere uygun olarak işleyişi sağlayabilmek için kapsülleme (Encapsulation) kavramından yararlanırız. Arabanın gaz pedalına basıp hızlanırken, arka planda gerçekleşen olayların bizden soyutlanması ve araç parçalarının kullanıcıdan korunması olarak düşünebilirsiniz. Size sadece gaza basıp hızlanmak kalır.

Bir sınıfın özniteliklerini miras alarak, daha farklı sınıflar oluşturmak için kalıtım (Inheritance) kavramı bize yardım eder. Standart bir araba tanımını taban alıp yeni bir araba çeşidi tanımlayabilirsiniz. Kasa ve kaldırıcı piston ekleyip bir kamyon tanımı oluşturmanız mümkündür.

OOP’nin belki de en kuvvetli tarafı olan çok şekilli olma, çok şekillilik, çok biçimlilik (Polymorphism) kavramı sayesinde daha yönetilebilir ve daha az kaynak harcanarak genişletilebilir tasarımlar yapabiliriz. Herhangi bir arabanın ve kamyonun hızlanması gaza basılarak yapılsa da, yani verilen komut aynı bile olsa, arka planda olan işleyiş biçimi, gerçeklik farklı olabilir. Çok şekilli olmanın esnekliği de burada yatar.

2. Giriş

Herkese Merhaba.

Bu yazı kapsamında nesne yönelimli programlamanın oturduğu zeminden, sağladığı avantajlardan, proje yönetimindeki rolünden ve terminolojisinden bahsetmeye çalışacağım. Üstelik hiç kod yazmadan!

Şimdiye kadar nesne yönelimli programlama öğrenmek için bir girişiminiz olduysa muhtemelen kavramlar arasında sıra sıra kodlama yaparak geçiş yaptınız. Ben de bu şekilde öğrenen birisi olarak çok fazla soru işaretini uzunca bir süre kafamda taşımıştım.

“Böyle bir yapıyı kullanmak neden gerekli ki?”

“Klasik yöntemlerle daha az kod satırı yazmak varken …”

“Şu, sınıf (class) ve nesne (object) arasındaki farkı hep karıştırıyorum ya :).”

Bütün bu soruların yarattığı karmaşıklığı çözebilmek adına nesne yönelimli programlamaya şöyle tepeden bir göz atacağız. Eminim ki kodlama kısmını öğrenmeye geçtiğinizde daha az soru işaretiyle ilerleyeceksiniz. Sonuçta, çıkılacak arazinin sınırlarını ve engellerini kabaca önceden bilmek büyük bir avantajdır.

Strateji: Önce büyük resmi anla, sonra detaylara (kodlama kısmı) odaklan.

Yazının sonunda sizlere nesne yönelimli programlamanın büyük resmini anlatmış olmayı umuyorum.

3. Nesne Yönelimli Olmanın Özü

Tek cümle ile OOP’nin ne olduğunu anlatmaya çalışsam şöyle basit bir cümle kurardım:

“Kodlama yapmayı insan algısına yaklaştıran ve kağıt üzerinde planlamayı kolaylaştıran bir TEKNİKTİR.”

Cümle içinde “ve” bağlacı kullanarak iki cümleyi teke düşürmüş olabilirim. İdare edin :). Nesne yönelimli programlama demek,

  • insan algısına yakın,
  • daha anlaşılır,
  • tasarlanması daha kolay,
  • yönetilebilir,
  • takım çalışması için uygun,
  • daha rahat güncellenebilir ve genişleyebilir

kod yazabilmek demektir. Özellikle kalın olarak yazdığım genişleyebilme kısmı, belki de OOP’nin en kuvvetli tarafıdır. Bu konuyu, “4.4. Çok Şekillilik (Polymorphism)” başlığında inceleyeceğiz.

“Nesne yönelimli programlamada karmaşıklık kod üzerinde değil, yazılım tasarımı üzerindedir.”

“Fonksiyonel programlamada ise karmaşıklık kod üzerindedir ve proje büyüdükçe yönetim zorlaşmaya başlar.”

Artık OOP’nin altında yatan felsefeyi anlamaya başlayabiliriz.

4. Nesne Yönelimli Programlamanın Yapı Taşları

4.1. Sınıf (Class) ve Nesne (Object)

Bu zamana kadar aşina olduğumuz fonksiyonel programlama ile nesne yönelimli programlamanın ayrımını biraz daha netleştirelim.

> Örnek-1: Sadece istediğiniz miktarı yazarak ATM’den para çekebildiğiniz ve yatırabildiğiniz bir dünya hayal edin. Sanırım kimse para yatırmazdı, ama örnek olması açısından böyle basit bir dünya düşünün :). Para yatırma ve para çekme işlemlerini temsil etmek amacıyla birkaç satırlık kod yazmaya karar verdiniz.

Fonksiyonel olarak, “int paraCek(int miktar)” ve “void paraYatir(int miktar)” gibi bir mantık izleriz. Para yatırma ve çekme fonksiyonları… Nesne tabanlı kodlama bağlamında şöyle bir soru yöneltmek istiyorum:

“Bu örnekteki hikaye kapsamında düşünürsek nesne olarak neyi nitelendirirsiniz?”

Cevabınız ATM veya para oldu sanırım. Eğer öyleyse yanıldınız, çünkü OOP konseptinde kurgu yaparken, direkt olarak “şunlar şunlar nesnedir” diye bir nitelendirme yapılamaz. Eğer yapabilseydik “Hangi ATM?” sorusuna cevap verebiliyor olmamız gerekirdi. Bu noktada zaten sınıf ve nesne arasındaki farkı yavaş yavaş kavramaya başlıyoruz. ATM cevabını verdiğinizi varsayarak anlatıyorum, ama mantık her şey için aynıdır, değişmez.

ATM, para çekebildiğimiz, para yatırabildiğimiz, ekranı olan ve başka bir çok öznitelik daha ekleyebileceğimiz bir makinedir. Bu tanımlama ile bir nesneyi değil, bir grubu — türü, yani sınıfı, tanımlamış oluyoruz. X Bankası ATM’si dediğimizde ise o sınıfa ait bir nesneden söz edebiliriz. Gidip dokunabileceğimiz, tuşlarına basabileceğimiz somut bir nesne oluşmuştur. Dünya üzerindeki tüm kodlarda ATM sınıfı aynı tanımlanmak zorunda da değil. Projeden projeye istenen öznitelikler değişebilir. İşin özümsenmesi gereken tarafı, sınıf ve nesne kavramlarının temsil ettikleridir.

> Sınıf = ATM => { Kapasite, Renk, Mevki, …, paraYatir(), paraCek(), … }
>
Nesne => { X Bankası ATM’si, Y Bankası ATM’si, … }

Sınıf ve nesne kavramları için şu soruları ipucu olarak kullanabilirsiniz:

Sınıf: “Nasıl ATM?” — Para çekilebilen, kapasitesi olan, yeri belli olan, …
Nesne: “Hangi ATM?” — Tarık Bankası ATM’si, …

“Nesne (Object): Bir sınıfın barındırdığı özniteliklerin hayat bulması ile ortaya konan ürünlerdir.”

Birkaç örnek daha verip tam olarak sınıf-nesne ayrımını görelim. Örnekleri konunun daha iyi anlaşılması için veriyorum. İlgili sınıfa ait nesneleri birebir gerçek dünya ile bağdaştırmaya çalışmayın. Şu şekilde düşünün:

“Bir adet sınıf tanımı var ve o sınıfın öznitelikleriyle hayat bulmuş birden çok nesne var.”

> Sınıf = Kuş => { Boy, Renk, …, kanatCırp(), yemekYe(), … }
>
Nesne => { Anka Kuşu, Bülbül, Serçe, Muhabbet Kuşu, … }

> Sınıf = İnsan => { Boy, Kilo, …, nefesAlVer(), yemekYe(), … }
>
Nesne => { Tarık, Ahmet, Medium.com’un Kurucusu, Şuradaki kişi … }

Sınıf (Class) ve nesne (Object) kavramları arasındaki ayrımı ve ilişkiyi temsil eden görsel.
Görsel 4.1.1. Sınıf (Class) — Nesne (Object) Ayrımı ve İlişkisi

Tam olarak sınıf-nesne ilişkisini karşılamasa da anlamayı kolaylaştırmak açısından bir benzetim daha yapmak istiyorum. Okuduktan sonra unutabilirsiniz :).

> Sınıf = Integer => { Kendine göre öznitelikleri zaten tanımlı }
>>> int onsekiz = 18;
>>> int dokuz;
>>> …
>
Nesne => { onSekiz, dokuz, … }

Sınıf ve nesne kavramını özellikle tek başlık altında açıklamak istedim ki ayrımını rahatça verebileyim. Artık kapsülleyebiliriz :).

4.2. Kapsülleme (Encapsulation)

Aslında bu kısım anlatması ve anlaması en kolay kısımlardan biri. Yukarıda vermiş olduğum ATM örneği üzerinden konuşabiliriz.

> Örnek-1: Kesin olarak bildiğimiz bir durum var ki bu da depolanacak paranın bir sınırı olduğu. Sonuçta ATM’nin bir kapasitesi var.

Bu bağlamda, istediğimiz miktarı tuşlayıp, “ver oradan 10.000 ₺” dediğimiz zaman “al sana 10.000 ₺” dememesi lazım :). Veya para haznesini halka arz edip, “herkes çekeceği miktarı kendi alabilir.” deme şansımız da yok. Bunu bir kurala bağlayıp, verilerin manipüle edilmesine engel olmalıyız.

  • Çekilmek istenen tutar, haznedeki tutardan fazla olabilir.
  • Yatırılmak istenen tutar, mevcut tutarın üstüne eklenince kapasiteyi aşıyor olabilir.
  • Günlük çekme limiti dolmuş olabilir.

“Kapsülleme (encapsulation): Kontrol altında tutulmak istenen özel verilerin erişimi sınırlandırılarak, bazı fonksiyonlar aracılığı ile bu verilerin dış dünyaya sunulmasıdır.”

Günlük hayattan bir örnek daha vererek anlatmaya çalışayım.

> Örnek-2: Bir kahve dükkanından kahve alacaksınız. Bu kahve dükkanının adı ise “Tarık Coffee Shop” olsun. Sıra size geldi ve sipariş veriyorsunuz.

Geçmiş bilgilerimizi de tazeleyerek bir göz atalım. Burada nesne “Tarık Coffee Shop” olmuş oldu. Öyle değil mi? Bir yerlerde öznitelikleri tanımlanmış olan “Coffee Shop” sınıfı olduğunu da unutmayalım. Kasiyere sipariş verme işlemi de “kahveSiparişEt()” fonksiyonu ile temsil edilsin.

> Hatırlatma: Sınıf — Nesne
>>> kuş — serçe
>>> insan — ahmet
>>> coffee shop — tarık coffee shop
>>> …

“Böyle bir işleyiş içerisinde kahve, su, süt vb. verilere kim erişim sağlamış olur? Siz mi yoksa kasiyer mi?”

Kapsülleme (Encapsulation) — Örnek-2 Sınıf — Nesne İlişkisini temsil eden görsel.
Görsel 4.2.1. Kapsülleme (Encapsulation) — Örnek-2 Sınıf — Nesne İlişkisi
Kapsülleme (Encapsulation) — Örnek-2 İşleyiş Mantığını temsil eden görsel.
Görsel 4.2.2. Kapsülleme (Encapsulation) — Örnek-2 İşleyiş Mantığı

Tabii ki kasiyer sizin adınıza bu işlemleri organize eder. Verileri size açmak yerine, gerekli olan bazı prosedürlere uyarak, arka planda kahvenizi hazırlar ve size sunar. Yani veriler ile kullanıcı birbirinden soyutlanmış olur (Data Abstraction — Data Hiding). O halde, haydi kalıtalım :).

4.3. Kalıtım (Miras) (Inheritance)

Bu kısmı iki adet örneklendirme yaparak anlatmak istiyorum, çünkü bazı örneklerin kod karşılıklarını hayal edip bir yere oturtmak zor olabiliyor. Veya size o an için anlamsız gelebiliyor. Tekrar tekrar hatırlatmak istiyorum.

“Örnekleri gerçek dünya ile birebir bağlamaya çalışmayın. Temsili olarak yeni bir dünya yaratıyoruz ve kuralları da biz belirliyoruz.”

İlk örnek, kalıtım mantığını daha iyi anlayabilmek adına gündelik hayatımızda yer edinmiş bir durum olacak. Kod kısmını hayal etmek burada anlamsız gelebilir. İştahınızı ikinci örneğe saklayın ve sadece anlamaya odaklanın :).

> Örnek-1: Evde pasta yapmaya karar verdiniz ve internetten “pasta tarifi” buldunuz. Yumurta, süt ve un. Sadece bu üç malzeme ile pasta yapılabildiğini kabul edin. Fakat bu oldukça sade bir tarif. Amacınız ise bir doğum günü pastası yapabilmek. Standart öznitelikleri olan pasta tarifinin üzerine yeni öznitelikler eklemek istiyorsunuz. Yumurta, süt ve un zaten standart olarak vardı. Siz ise bu tarife kakao, muz ve çikolata ekleyip “doğum günü pastası tarifi” oluşturdunuz.

“pasta tarifi” ve “doğum günü pastası tarifi” kısımlarını özellikle kalın hale getirdim ki yeri gelmişken bir sınıf — nesne belirlemesi daha yapalım. Hemen hızlıca cevaplayın! :).

“Bu iki tarif, sınıf mı yoksa nesne midir?”

Sınıf: “Nasıl Pasta?”
Nesne: “Hangi Pasta?”

Evet, “pasta tarifi” ve “doğum günü pastası tarifi” birer sınıfı temsil eder. Çünkü “Nasıl Pasta?” sorusunun cevabı tariflerdedir. Bu sınıflardaki özniteliklere göre bir pasta yapıldığında ise nesneden söz edebiliriz. Artık sınıf — nesne karmaşasını bir nebze olsun yok edebildiğimizi düşünüyorum.

“Peki, kalıtım bu işin neresinde?”

Tıp terminolojisinde, “kalıtım bilimi” ile “genetik” aynı olguları karşılar (Bkz. Türk Hematoloji Derneği — Genetik Terimler Sözlüğü). Yani bir şeyden kalıtım almak demek onun genini almak, ondan miras olarak bir şeyler taşımak demektir.

> Taban Sınıf = pasta tarifi => { yumurta, süt, un }
>>> Kalıtım: pasta tarifi →doğum günü pastası tarifi
> Türetilen Sınıf = doğum günü pastası tarifi => { ( yumurta, süt, un ), kakao, muz, çikolata }

> Nesne => { Tarığın doğum günü pastası, dolaptaki doğum günü pastası, … }

Örneğimizde de görüldüğü üzere, “pasta tarifi”nin özniteliklerini miras alıp “doğum günü pastası tarifi”ni elde ettik. Orijinal tarifteki yumurta, süt ve un miras olarak taşındı ve biz yeni öznitelikler olarak kakao, muz ve çikolatayı ekledik.

Kalıtım (Inheritance) — Örnek-1 Sınıf Hiyerarşisini temsil eden görsel.
Görsel 4.3.1. Kalıtım (Inheritance) — Örnek-1 Sınıf Hiyerarşisi

Taban Sınıf: Base Class
Türetilen Sınıf: Derived Class

“Kalıtım (Inheritance): Bir sınıfın öznitelikleri miras alınıp, bazı farklı öznitelikler daha eklenmesi ile yeni sınıfların oluşturulmasıdır.”

İkinci örneğe gelecek olursak, programlama kısmını hayal edebilmek açısından daha uygun olacaktır diye düşünüyorum.

> Örnek-2: Burada bir hikayeleştirme yapmayacağım. Ancak sizin kafanızda bir şeyler canlandırmak istiyorum. Şimdi, telefon kelimesi ile aklınızda ne oluşuyorsa bir kenara yazın. Fakat herhangi bir telefonu düşünmeyin. Kavramsal olarak, en ilkel hali ile ne ifade ediyorsa onu düşünün. Birkaç kelime daha vereceğim. Bunları da sadece kavramsal olarak hayal edin. Ev telefonu, akıllı telefon, halka açık telefon,

Kalıtım (Inheritance) — Örnek-2 Sınıf Hiyerarşisini temsil eden görsel.
Görsel 4.3.2. Kalıtım (Inheritance) — Örnek-2 Sınıf Hiyerarşisi

“Birkaç istisna durum dışında, taban sınıfta bulunan öznitelikler türetilen sınıfa tekrar yazılmaz. Kalıtım ile geçtiği zaten bilinir. Rahatça inceleyebilmek amacıyla mirasları kalın ve altı çizili olarak yazdım.”

Kalıtım kullanırken istediğiniz kadar sınıf türetebilir ve istediğiniz kadar da öznitelik ekleyebilirsiniz. Ben görsellerin ve örneklerin sadeliği bozulmasın diye kısa tutmaya çalışıyorum. Çözmeniz gereken problemin ihtiyaçlarına göre tasarım elbette değişecektir. Belki de sizin probleminizdeki telefon kavramı çok farklı şekillenecek. Ek bir bilgi olarak, türetilen sınıftan tekrar sınıf türetme gibi aksiyonlar da mevcut. Ancak şu an kavramları özümsemeyi amaçladığımız için buna benzer teknikler kodlama pratiği yapılırken öğrenilmeli.

Şimdi de biraz çok şekilli olalım, iki yüzlü olalım, hayın olalım, … :) (Bkz. Ahmet KURAL).

4.4. Çok Şekillilik (Polymorphism)

Şu aşamaya kadar sabırla ve anlayarak geldiysek bundan sonrası oldukça kolay olacaktır. Özellikle kalıtım kavramını özümsemiş olmak önem arz ediyor.

Çok şekillilik, adından da anlaşılacağı üzere çok şekilli olmayı, bir sıvı misali girilen kabın şeklini almayı gerektirir. Bu bağlamda, düşünme tarzımızı tekrar modellemek gerekebilir. Çok şekilli olma kavramını anlamak için hemen kafanızda iki adet bölme oluşturun.

“Bir tanesine ‘birden fazla şeyi iyi öğrenebilme, uygulayabilme’ olgusunu yerleştirin.”

“Diğerine ise ‘bir işin ustası olma, o işi çok iyi icra edebilme’ olgusunu yerleştirin.”

Bunlar kafamızda durmak kaydı ile biraz laf kalabalığı yaparak olayı hikayeleştirelim. Alışkanlık oldu artık :).

> Örnek-1: Bir şirket düşünün. Birden fazla departmanı var. Yazılım departmanı, muhasebe departmanı, Ar-Ge departmanı, … Şirket yöneticisi Hamdi Bey, bu departmanların performanslarını haftalık olarak görmek istiyor. Her bir departmanı tek tek takip etmek yerine tüm departmanların performans hesaplarını uygulayabilecek yetenekte olan Seda Hanımı işe alıyor. Yani Seda Hanım, “birden fazla şeyi iyi öğrenebilme, uygulayabilme” kabiliyetine sahip. Fakat bu hesapları uygulayabilmesi için her departman kendi hesap yöntemini bildirmeli. Yani bu yöntemleri bildiren departman sorumluları, “bir işin ustası olma, o işi çok iyi icra edebilme” kabiliyetine sahip. Hamdi Bey çok mutlu :). Çünkü artık muhatap olduğu tek kişi var.

“Şimdi, bu hikayede ne olmuş oldu?”

Seda Hanım, çok şekilli bir forma büründü ve performans hesaplamalarını halledip Hamdi Beye raporladı. Böyle bir yapıyla beraber gelen çok önemli bir kazanım var. Yeni departmanlar eklense bile Hamdi Bey tarafında hiçbir değişiklik olmaz. Çünkü departmanların performans hesaplarını uygulayıp raporlayan Seda Hanım var.

Çok Şekillilik (Polymorphism) — Örnek-1 Sınıf Hiyerarşisini temsil eden görsel.
Görsel 4.4.1. Çok Şekillilik (Polymorphism) — Örnek-1 Sınıf Hiyerarşisi

Bu noktada, kalıtım kısmında öğrendiğimiz bir bilginin istisnasını konuşmalıyız. Taban sınıftaki her şey, türetilen sınıfa miras olarak geçer ve tekrar yazmaya gerek yoktur, demiştik. Fakat çok şekilli bir yapı tasarlarken, hangi işlevin çok şekilli olarak davranmasını istiyorsak, onun kendine has işleyişini ilgili yerde belirlemeliyiz. Görsel üzerinden de açıklayıp pekiştirelim.

Her departman sorumlusunun performans hesaplama yöntemi farklıdır, dedik. performansHesapla() fonksiyonu miras olarak taşınmasına rağmen ilgili yerde o performansın nasıl hesaplanacağı özel olarak detaylandırılmalıdır. Bu sayede her bir departman sorumlusu, kendinde bulunan performansHesapla() fonksiyonunu alır ve genel departman sorumlusunun performansHesapla() fonksiyonunun üstüne bindirir. Bir anlamda ona hesaplama yöntemini öğretir, diyebiliriz. Bu kavramın adı ise fonksiyon üzerine bindirme (Function Overriding) olarak geçer.

“Çok Şekillilik (Polymorphism): Birden fazla sınıfta aynı amaca hizmet eden, fakat işleyiş biçimleri bakımından farklılık gösteren fonksiyonların, hiyerarşideki daha üst bir sınıf üzerinde çalışması sayesinde yönetimin bir merkezde toplanmasıdır.”

Çok Şekillilik (Polymorphism) — Örnek-1 Hikayesini temsil eden görsel.
Görsel 4.4.2. Çok Şekillilik (Polymorphism) — Örnek-1 Hikayesi

Bakıldığı zaman, türetilen her sınıftan sadece bir adet nesne yaratılmış oldu. Ancak yanlış bir algı oluşmasın. İstediğiniz kadar sınıf türetip, istediğiniz kadar da nesne yaratabilirsiniz. Aynı sınıftan veya farklı sınıftan… Fark etmez.

“Peki, taban sınıftan Seda Hanım gibi bir nesne daha türetebilir miyiz?”

Yerine göre evet. Yerine göre de hayır. Cevabın hayır olduğu yerde zaten herhangi bir nesneden, yani Seda Hanımın varlığından, dahi bahsedilemez. Böyle bir durumda da arayüz (Interface) ve soyut sınıf (Abstract Class) kavramları karşımıza çıkar. Soyutlama (Abstraction) başlığı altında anlatılan bu kavramları, yani işlevselliğin soyutlanmasını, şu anlık kulak aşinalığı olacak kadar bilmeniz yeterli. Detaylarını kodlama kısmında tecrübe etmeniz daha sağlıklı olacaktır.

Olaya başka bir açıdan daha bakalım. Bu sefer biraz eğlenceli bir örnek olsun. Oyun konsolunda oyun oynasak fena olmaz. Bu örnekte hikayeyi anlatıp, görselini de verip bazı şeylerin tespitini size bırakacağım. Tıkanırsanız Seda Hanıma sorabilirsiniz :).

> Örnek-2: Bir adet oyun konsolu aldınız. Beraberinde bir sürü de oyun aldınız. Bildiğiniz üzere, tek bir konsol ile birçok oyunu oynayabilirsiniz. Yani oyun konsolu, “birden fazla şeyi iyi öğrenebilme, uygulayabilme” kabiliyetine sahip. Fakat oyunları çalıştırabilmesi için herhangi bir oyun CD’si takılmalı. Yani oyun grafiklerini, karakter hareketlerini, hesaplamaları barındıran oyun CD’leri, “bir işin ustası olma, o işi çok iyi icra edebilme” kabiliyetine sahip.

Bu örnekte;

“Çok şekilli olan şey nedir? Nasıl bir kazanım elde ettik?”

Çok Şekillilik (Polymorphism) — Örnek-2 Sınıf Hiyerarşisini temsil eden görsel.
Görsel 4.4.3. Çok Şekillilik (Polymorphism) — Örnek-2 Sınıf Hiyerarşisi
Çok Şekillilik (Polymorphism) — Örnek-2 Hikayesini temsil eden görsel.
Görsel 4.4.4. Çok Şekillilik (Polymorphism) — Örnek-2 Hikayesi

İşin mantığını tam anlamıyla özümsemek ve kodlama kısmını kafamızda daha iyi canlandırabilmek için son bir örnek daha yapalım. Önceki örneklerin yalın ve kuvvetli anlatım yapabilmek gibi bir misyonu vardı. Sonuncu ise kodlama tarafında daha anlamlı olacak bir örnek olsun. Sonrasında ise kapanış konuşmasına geçebiliriz.

Şuan aklıma şöyle bir şey geldi; Bu yazı bir Türk dizisi olsaydı tam burada reklam girebilirdi :). Neyse ki böyle gereksiz heyecanlara blog yazılarında yer yok!

Bu konunun vazgeçilmez örneklerinden birisi de iki boyutlu geometrik şekillerin alan, çevre vb. hesaplamalarının yapılmasıdır. İyi bir örnektir. Bu konunun “Hello World”ü gibidir dersek yanlış olmaz :). Haydi, göz atalım.

> Örnek-3: Dünya üzerindeki tüm geometrik şekillerin eni, boyu, alan hesabı, çevre hesabı gibi bazı öznitelikleri vardır. Fakat her şeklin alan ve çevre hesabı aynı mıdır? Elbette hayır. Bu örnekte, sadece alan hesabını ele alalım.

“Her üçgenin alan hesabı aynı değildir ki!” diye itiraz etmeyin diye aşağıdaki formüller ile hesaplandığını kabul edin :).

* Üçgenin Alanı = (taban * yükseklik) / 2
* Dikdörtgenin Alanı = taban * yükseklik
* Dairenin Alanı = π * (r²)
* …

Çok Şekillilik (Polymorphism) — Örnek-3 Sınıf Hiyerarşisini temsil eden görsel.
Görsel 4.4.5. Çok Şekillilik (Polymorphism) — Örnek-3 Sınıf Hiyerarşisi
Çok Şekillilik (Polymorphism) — Örnek-3 Hikayesini temsil eden görsel.
Görsel 4.4.6. Çok Şekillilik (Polymorphism) — Örnek-3 Hikayesi

Yönetici şeklin, nasıl bir şekil olduğunu düşünmeye çalışacaklar için sesleniyorum. DÜŞÜNMEYİN! :). Gerçek hayatta karşılık bulabilecek bir şey değil. Çok şekilliliğin tanımında da belirttiğimiz üzere bu yaklaşım, türetilen sınıflar için bir yönetim merkezi vasfındadır (Hatırlayın: Arayüz (Interface) ve Soyut Sınıf (Abstract Class)).

5. Sonuç

Nihayet sonuna gelebildik. Nesne — sınıf ayrımından, kapsüllemeden, kalıtımdan ve çok şekilli olmadan bahsettik. Örneklerle detaylandırıp, görseller ile daha anlaşılır kılmaya çalıştık.

Bu yazıya başlamaya karar verdiğimde, bu denli vaktimi alacağını düşünememiştim. Elimden geldiğince anlaşılır, detaylı ve okunaklı yazmaya özen gösterdim. Üşenmedim, tek tek görselleri de kendim hazırladım. Tabii ki bazı ücretsiz ikonlardan da yararlandım :) (Bkz. Flat Icon). Umarım, nesne tabanlı programlamanın felsefesi anlaşılmıştır ve artık herhangi bir eğitim setinden kodlama kısmını öğrenirken rahat edebilirsiniz.

Nesne tabanlı programlama mantığını özümsedikten sonra sınıf diyagramları (U.M.L.), tasarım prensipleri, tasarım kalıpları gibi bazı konuları da bilmekte yarar var. Vakit buldukça ve iyi anlatabileceğim konusunda ikna olursam, bu konuları da aktarmaya çalışırım. Bazılarını ben de henüz öğreniyorum ve konuları kavradıkça buradan paylaşmak gibi bir niyetim var. Naçizane, becerebildiğim kadarıyla yardımcı olabilirsem ne mutlu…

Hoşça kalın.

--

--