Polymorphism — Çok Biçimlilik
Object Oriented Programming (OOP) yazısında bahsettiğimiz gibi OOP 4 temel özellik üzerine kurulmuştur. Bu yazımızda bu 4 temel taştan biri olan Polymorphism yani Çok Biçimlilik hakkında konuşacağız. Keyifli okumalar..
Öncelikle Polymorphism kelimesinin kökenine bakalım. Latincede “poly” çok, “morphos” ise biçim veya şekil anlamına gelmektedir. Bu nedenle polymorphism kelimesi “çok şekillilik” veya “çok biçimlilik” olarak adlandırılmaktadır.
Polymorphism yani çok biçimlilik kavramı birçok türe sahip olmak anlamına gelir ve aynı görevin veya işin farklı yollarla yapılabilmesini sağlar. Başka bir ifadeyle, oluşturduğumuz bir nesnenin farklı nesneler gibi davranabilmesini sağlar.
Aslında Polymorphism bir yaklaşımdır, Upcasting ise onu gerçekleştiren mekanizmadır. Upcasting için kısaca, sub tipteki (alt tipteki) bir nesnenin referansını üst tipten bir referansa atamak diyebiliriz. Yani bir Baseclass, ondan türeyen subclass’ların referansını tutabilir.
Aslında Polymorphism, Kalıtım(Inheritance) kavramı ile iç içe olduğu için bu yapıyı anlayabilmek için kalıtımın ne olduğunu bilmeniz gerekmektedir. Eğer bu konuda kendinizi eksik hissediyorsanız Kalıtım isimli yazıma bakabilirsiniz.
Peki, bu kadar şey anlattık. Tüm bunlar ne anlama gelmektedir? Gelin uygulamalı olarak birlikte öğrenelim.
Bir tane A class’ımız olsun. Bu class’ın “run” adında bir metodu bulunsun.
Bir tane de B class’ımız olsun. B class’ı, A class’ını extends etsin ve run metodunu Override etsin, ayrıca bir tane de “stop” isimli bir metodu bulunsun.
B class’ı, A class’ını extends ettiği için B class’ını new’leyerek oluşturulan bir nesne artık A class’ı tipinde gibi davranabilir. İşte bu yapı polimorfik bir yapıdır.
Peki bu durumda xNesnesi üzerinden run metodu çalıştırıldığında A sınıfının run metodu mu çalışır? B sınıfının run metodu mu çalışır?
xNesnesi her ne kadar A tipinde olsa da, B sınıfı A sınıfından türetildiği için öncelikli olarak B sınıfının run metodu çalışacaktır.
Peki B class’ındaki run metodunu silseydik. Yani artık run metodu Override edilmeseydi çıktı ne olurdu ?
Aşağıda görüldüğü gibi artık ekranda “A kişisi koşuyor” yazacaktır. Çünkü B sınıfından türetilen xNesnesi run metodunu kendi sınıfından çağırmaya çalışacaktır ama böyle bir metot bulamayınca extends ettiği bir üst sınıfa bakıp bu sınıfın run metodunu çağıracaktır.
Peki xNesnesi üzerinden B class’ının stop metoduna erişmek isteseydik ne olurdu?
Evet, tahmin ettiğiniz üzere bu metoda erişim sağlayamazdık. Çünkü A class’ı üst sınıf, B class’ı onu extends eden alt sınıftır ve alt sınıflar üst sınıfların özelliklerine/metotlarına erişim sağlayabilse de üst sınıflar alt sınıfların özelliklerine/metotlarına erişim sağlayamaz.
Buraya kadar Polymorphism kavramını az çok anladığımızı, en azından kafamızda bir şeyler oluştuğunu düşünüyorum.
Şimdi gelin daha detaylı başka bir örneği inceleyelim.
Bir tane “Canlı” adında üst sınıfımız olsun ve bu sınıfın “yaz” isimli bir metodu olsun. Bu üst sınıfı extends eden “Insan”, “Hayvan” ve “Bitki” isimlerinde alt sınıflar olsun ve bu sınıflar da yaz metodunu Override etsin.
Şimdi de bir tane Polymorphism isimli bir sınıf oluşturalım ve bu sınıfın içerisinde “nesneAl” isimli bir metot oluşturalım.
Görüldüğü üzere nesneAl isimli metot Canli tipinde bir parametre almak istemektedir. Şimdi main metoda gidelim, Canli tipinde bir nesne oluşturalım, oluşturduğumuz nesnemizi bu nesneAl metoduna verelim ve çıktıyı görelim.
Canli sıfından bir nesne oluşturup bu nesneyi nesneAl isimli metoda attığımız zaman çıktımızın “Canlı Sınıfı” olduğunu görmekteyiz. Peki biz bu metoda alt sınıflarımızda oluşturduğumuz nesneleri atabilir miyiz ? Gelin alt sınıflardan nesne oluşturalım ve sonuçlara bakalım.
Görüldüğü gibi alt sınıflardan da nesneler oluşturduk ve bu nesneleri nesneAl isimli metoda parametre olarak gönderdik. Peki bunu nasıl yapabildik? nesneAl metodu Canli tipinde parametre kabul etmiyor muydu? Bu nesnelerin tipleri farklı olmasına rağmen nasıl kabul etti?
Bu metoda farklı tipte parametreler gönderebilmemizin ana sebebi bu nesnelerin sınıfları Canli sınıfının alt sınıflarıdır. Yani bu sınıflar zaten Canli sınıfından türediği için, bunların nesneleri de Canli sınıfı tipinde gibi davranıyorlar diyebiliriz. Bu yüzden de nesneAl metodumuz bu nesneleri kabul etmiştir.
İşte tam da burada Polymorphism’in Kalıtım ile olan ilişkisini anlayabiliriz. Alt sınıflardan oluşturulan nesneler, üst sınıfın referansına bağlanabilir ! Yani üst sınıflar, alt sınıfların referansını tutabilirler.
Yani özetle buradaki asıl olay şudur: Bir nesnenin birden fazla nesneye bağlanabilmesidir.
Örneğimizde de bu nesnelerin hepsinin tipini Canli olarak değiştirirsek hiçbir şey değişmeyecektir. Çünkü bu nesneler zaten Canli tipindeymiş gibi davranmaktadırlar.
Görüldüğü gibi nesnelerin tipi değişse de çıktılarımızda bir değişiklik olmamıştır. İşte bize kolaylık sağlayan bu yapıya Polymorphism diyoruz.
Umarım keyifli ve açıklayıcı bir okuma olmuştur. Hepinize iyi çalışmalar diliyorum.. ✨