Nesne Yönelimli Programlama -5- Polymorphism

Merhaba sevgili yazılım aşıkları. Nesne yönelimli programlama konulu eğitsel makale serimize devam ediyoruz. Bu yazımda ele alacağım konu, “çok biçimlilik” olarak türkçeye çevrilebilecek olan ve yine, nesne yönelimli programlama kavramının temellerinden olan polymorphism olacak.

İnanın böyle ciddi cümleler kurmak beni biraz sıkıyor dostlarım. O nedenle, izin verirseniz rahat rahat, geyik yapa yapa size bu kavramı sunmaya çalışacağım (Gerçi, izin vermeseniz de böyle olacak ama neyse).

Sevgilli dostlar, çok biçimlilik kavramını iyi anlayabilmek için miras kavramı hakkında kafamızda hiçbir soru işareti kalmamalı. Eğer o konuda sorun varsa sizi oraya alayım. Şimdi çok biçimlilik kavramını anlamak üzere yine bir nesne modelleyelim isterseniz. Bu kez bir e-ticaret sitesinde, ürün satışı yapmak için kolları sıvıyoruz. Bu e-ticaret sitemiz, sanal market olsun. Yani hem gıda hem de elektronik ürünleri satabilecek bir portal. Site kullanıcısı, satın almak istediği ürünü sepete ekler. Siparişi vermeden önce, sepetteki tüm ürünlerin fiyatları toplanır ve ödenmesi gereken miktar belirlenir. Ha unutmadan, doğal olarak bu ürünlerin KDV oranları da farklı (haydi hayırlısı) olacak ve elbette fiyat ona göre hesaplanacak.

Haydi bakalım. Öncelikle dilerseniz Urun isminde bir sınıf oluşturalım. Site üzerinden satışını gerçekleştirdiğimiz tüm ürünlerin ortak alanları burada olsun.

Sınıf üyelerim gayet basit gördüğünüz gibi. Buradaki amacım, size çok biçimlilik kavramını anlatabilmek olduğu için, diğer sınıflarımın da basit olmasına özen göstereceğim (bazen böyle açıklamaları neden yaptığımı hiç anlayamıyorum. Boşverin takılmayın siz.). Bu sınıfta KDVUygula metoduna dikkat!! Varsayılan olarak, ürün fiyatına %8 oranında KDV uyguluyorum.

Peki gelelim diğer sınıflara. Urun sınıfından Tekstil, CepTelefonu ve kuru gıda ürünlerini temsil edecek sınıflarımı türetiyorum. Evet.. e dedim ya polymorphism’i anlamak için miras kavramını bilmek gerekir diye… Her neyse.

Tekstil:

Cep telefonu:

Ve… Ekmek:

Peki, şimdi de Sepet sınıfımızı yazalım. Bu sınıf, ürünlerimizi taşıyacak ve “ödenmesi gereken tutar” ı bizim için hesaplayacak.

Şimdi, bu makaleyi yazarken, doğru KDV oranlarını bulmak için bu siteye baktım durdum. Ekmeğin KDV oranı %1, cep telefonu %18, tekstil ürünlerinin ise %8. Şöyle kolay hesaplayacağımız örnek fiyatlar vererek, elde etmemiz gereken KDV dahil fiyatları bir görelim. Eğer ekmeğin kdv hariç fiyatı 10 kuruş olsaydı, KDV dahil fiyatı 10 x 1.01 = 10,1 kuruş olacaktı. Peki bakalım bizim şu sınıflar, bu fiyatı hesaplayabilecek mi? Görelim:

..ve sonuç:

Hmm… İşte sorun! Ama bu sorunu, eminim ki teşhis etmişsinizdir. İçinizden diyorsunuz ki, “eh be şişman adam, Urun sınıfındaki KDVUygula metodu varsayılan olarak %8 vergi uygularsa böyle olur”. Peki tamam. Nasıl çözeceğiz o zaman bu sorunu? KDVUygula metodunu Urun sınıfından kaldırmamı beklemeyin. Çünkü tüm ürünlerimde (tekstil,cep telefonu ve ekmek) bu metod var. O zaman şöyle diyebilir miyiz, evet tüm ürünlerde KDVUygula olmalı ama, hepsinde FARKLI çalışmalı! Evet işte şu an da çok biçimli olması gereken bir KDVUygula metoduna ihtiyaç duyuyorsunuz! Hazır bu ihtiyacı duymuşken, şu polymorphism’in tanımını bir yapalım. Temel sınıftan, türetilmiş sınıfa kalıtım yoluyla aktarılan, fakat türetilmiş sınıfta farklı bir şekilde kullanılabilmesine izin verilen sınıf üyesi, çok biçimli bir üyedir. Buraya kadar bu yazıyı okumuşsanız, hala sıkılmamışsınız demektir. Öyleyse, bir şişman adam örneği hakettiniz!

Çok değil bundan bir elli atmış yıl önce, babalarımız dedelerimiz bizden çok daha doğal besleniyorlardı öyle değil mi? Fakat biz, hazır yiyeceklerle biraz daha haşır neşiriz. Peki bu beslenme dediğimiz olay canlıların tümünden bize kalıtımla aktarılan birşey değil mi? Evet ama, kalıtımdan kalıtıma bu beslenme şekli oldukça değişmiş! İşte size, atalarımızdan aldığımız çok biçimli bir metod… Beslenme metodu!

Peki, bu çok biçimliliği kendi sınıfımıza uygulama zamanı geldi. Bakın Urun sınıfımdaki KDVUygula() metoduma ne yapıyorum:

“virtual” anahtar kelimesini ekleyerek metodumun çok biçimli bir metod olduğunu gösterdim. Şimdi de, bu metodun yapısını, türemiş sınıflarımda nasıl değiştireceğime bakalım. Hemen Ekmek sınıfına gidelim ve override kelime sini yazdıktan sonra neler geldiğine bir bakalım:

İşte! KDVUygula orada! Demek ki sadece virtual imzalı sınıf üyeleri override edilebilirler (Bu arada override; çiğnemek,ezmek anlamına gelir ). Biz KDVUygula metodunu seçerek yola devam edelim ve metodun gövde kodunu değiştirelim:

Şimdi az önce yanlış hesapladığını gördüğümüz kodu tekrar çalıştırıyorum. Bakalım sonuç ne olacak:

İşte bu! Çok biçimlilik bir kez daha günü kurtardı. Teşekkürler nesne yönelimli programlama, teşekkürler çok biçimlilik.

Buraya kadar, aklınızda bir soru işareti kalmış olabilir.. Yukarıda override kelimesini “ezmek” olarak tanımlamıştım. Peki kim neyi eziyor? Biraz buraya odaklanalım. Unutmayın ki, bu örnekte tüm ürünlerimde KDV uygulanması gerektiğinden dolayı Urun sınıfına KDVUygula metodunu ekledim. Sepet nesnesinde ödenecek tutarı hesaplarken de urun nesnesinin KDVUygula metodunu kullandım. Yine örnekte sepet.Ekle(Urun urun) metodunu kullanarak bir Ekmek nesnesini, sepete ekledim. Aradaki miras ilişkisi sayesinde bunu yapabildim. Sonuç olarak, Ekmek sınıfı içinde yer alan KDVUygula metodu, Urun içindeki KDVHesapla metodunu geçersiz kıldı yani ezdi. Böylece, ekmek için %1 KDV uygulanması gerektiğini belirtebildim.

İşte sevgili dostlarım. Nesne Yönelimli Programlama dünyasının bu karışıkmış gibi görünen polymorphism konusunun da aslında ne kadar basit olduğunu göstermiş bulunuyoruz. Unutmayın; karmaşık olan şeyler basit geldiğinde, kendimizi geliştirmişiz demektir.

Sağlıcakla kalın.

Türkay

23 thoughts on “Nesne Yönelimli Programlama -5- Polymorphism

  1. Oop ‘deki en önemli kavram bu gerçekten.. Çoğu design pattern bu kavram etrafında dönüyor..Dll kodlarken bolca karşımıza çıkıyor..En basit düzeyde süper anlaşılır anlatmışsınız.Bunu okuyupta anlamayanı döverler gerçekten : P

  2. Her zamanki şişman adam tadında, son derece anlaşılır ve esprili bir dille yazılmış bir makale daha. "Gülümseyerek makalemi okunur" demeyin, şişman adamı deneyin!

  3. Hocam size asp.net.tr sitesinde yayınlanan makalelerinizden ulaştım. OOP makale serilerinizi büyük bir zevkle okudum. Gerçekten bu işe yeni başlayan biri olarak anlatımlarınızdan çok faydalandım. OOP mantığını anlamaya çalışıyordum. Bu tarz makaleleri hazırlayıp bizlere sunduğunuz için çok teşekkür ederim. Bu arada son paragrafta belirttiğiniz KDVHesapla metodu sanırım KDVUygula metodu olacak değil mi hocam. Saygılar

  4. Paylaşım için teşekkürler.. Bende yer yer blogumda c# üzerine yazılar yazıp bir şeyler anlatmaya çalışıyorum. Ama inanın bu konuya hiç cesaret edememiştim. İnsanların kafasını daha da karıştırmaktan korkmuştum. Anlatımınız gerçekten çok başarılı.. meslektaşınız olarak sizi takdir ediyorum..

  5. Hocam bu konuyu çok güzel anlatmışsınız. Bir çok yerde okudum ama bu kadar anlaşılabilir olanı ilk defa okuyorum. Paylaşım için çok teşekkürler.

  6. polymorphism ve abstract method arasındaki farkı ayırt edemiyorum.
    kullanım seklı olarak tamam farklı ancak kullanım alanları olarak koca bir ? ine sahibim.Hangi durumda hangisini kullanıcağım.Sisman ve evli adam dan 😀 müsait oldugunda açıklayıcı bır cevap beklıyorum.

    1. Selamlar, eğer hala sorunuzun cevabını bulamadıysanız yada benim gibi sorunuzu görünce aklına “harbiden ne acaba?” gibi bir soru takılan diğer arkadaşlar için benim araştırıp, anladığım kadarıyla abstract metodların gövdeleri yok dolayısıyla her mirasta yeniden override edilerek tanımlanmaları gerekiyor, diğer bir deyişle polymorphismde sınıf içerisinde varsayılan olarak bir metod tanımlanıyor, abstract metodlarda ise varsayılan bir gövde bulunmuyor. Yanlışım var ise biri beni düzeltsin. 🙂

    1. Merhaba;

      Eposta ile size yanıt döndüm ancak okuduğunuzdan emin olamadım. Dolayısıyla aynı yanıtı burada da vereceğim.
      Yorumunuzda belirtmiş olduğunuz video, 2015 yılına ait. Benim makalemin arşiv tarihi ise 2012. Ayrıca iliştirdiğiniz
      videodaki meslektaşım, internetten konu ile ilgili olarak bir örnek aradığını ve bir sitede bu örneği bulduğunu ifade ediyor.

      Acaba o, “bir site” turkayurkmez.com olabilir mi?

      Gördüğünüz gibi, benim yazdığım tarihten 3 yıl sonra çekilmiş bir videodan alıntı yapmam imkansız olduğuna göre
      alıntı yapan ben değilim.

      Sonuç olarak insanları herhangi bir şekilde itham etmeden önce, minicik de olsa bir araştırma yapın derim.
      İyi çalışmalar.

    1. Merhaba. Söz konusu soruya çok basitçe yanıt vermek isterim. Bir sınıfın bir metodunu, virtual olarak imzaladığınızda, o sınıfı miras alan diğer sınıflara “isterseniz bu metodu ezebilirsiniz” mesajı vermiş olursunuz. Yani ezme zorunluluğu yoktur. Fakat eğer bu metodu ve doğal olarak sınıfı abstract olarak imzalarsanız, bu kez mirasçılara verdiğiniz mesaj başkadır: “bu metodu ezmeye MECBURSUNUZ”. Kısacası, abstract metod, polimorfizmi zorunlu kılar.

    1. Peki öyleyse polymorphism nedir?
      Polymorphism is often referred to as the third pillar of object-oriented programming, after encapsulation and inheritance. Polymorphism is a Greek word that means “many-shaped” and it has two distinct aspects:

      *At run time, objects of a derived class may be treated as objects of a base class in places such as method parameters and collections or arrays. When this occurs, the object’s declared type is no longer identical to its run-time type.

      *Base classes may define and implement virtual methods, and derived classes can override them, which means they provide their own definition and implementation. At run-time, when client code calls the method, the CLR looks up the run-time type of the object, and invokes that override of the virtual method. Thus in your source code you can call a method on a base class, and cause a derived class’s version of the method to be executed.

      Devamı için: https://docs.microsoft.com/tr-tr/dotnet/csharp/programming-guide/classes-and-structs/polymorphism

Leave a Reply