OOP: Polimorfizm

Kapsülleme ve kalıtım konularından sonra sıra geldi polimorfizme. Polimorfizm, Türkçe’de çok biçimlilik olarak çevriliyor. Polimorfizmi anlatmak için JUnit in Action kitabında gördüğüm güzel bir örneği vereceğim. Bu örnek sayesinde polimorfizm’in kullanım amacını da göstermiş olacağım. Örnek göstererek anlatmayı daha uygun buldum. Ben önce örnekleri inceleyip sonra açıklamaları okurdum. Bu sayede daha kolay kavrıyorum. Aynı yöntemi burda da uygulayacağım. Bu konuyu kavramanız için kalıtım konusuna hakim olmanız gerekmektedir.

 

Örneğimiz de bir yazıcımız (Printer) var.  Bu yazıcı word (kelime işlemci)  ve pdf belgelerini yazdırıyor. Bu sınıflar aşağıdaki gibidir.

PDF ve Word sınıfları print isimli bir metodu içeriyor. Şimdi de yazıcı (Printer) sınıfımıza bakalım.

Printer sınıfımızın ise iki metodu var. printPDF metodu PDF dökümanını, printWord metodu ise word dökümanını yazdırıyor. Bu metodlar bu nesneleri parametre olarak alıp, PDF ve Word sınıflarının print metodunu kullanıyor. Buradaki sorun Printer sınıfının aynı işi yapan iki metod barındırması. Ayrıca bu esnek bir yapı değil. Şu anda bu size pek sorun olarak gözükmeyebilir. Bunu da şöyle örneklendirelim: Müşteriniz Word ve PDF dökümanlarını sorunsuz yazdırdığını fakat bir de sunum dosyasını yazdırmak istedi. Bunun için muhtemelen Presentation diye bir sınıf ekleyip, Printer sınıfına printPresentation metodu ekleyeceksiniz. Bu sefer aynı işi yapan 3 metodunuz olacak. Başka bir tipte döküman yazdırmak istediğinde metod sayısı artacak. Bu durum Açık-Kapalı (Open-Close) prensibine aykırı bir durum. Açık-Kapalı prensibine göre yazdığımız kodlar gelişime açık fakat değiştirilmeye kapalı olmalıdır. Burada sürekli Printer sınıfı değiştirilmektedir. Yeni bir döküman yazdırma özelliğini eklemek istediğimizde Printer sınıfını değiştirmeden yapmamız gerekmektedir.

Şimdi bu sorunu çözelim. Word ve PDF sınıflarının bir ortak özelliği var: İkisi de döküman. Bir döküman sınıfı oluşturalım.

Şimdi Word ve PDF sınıflarımız, Document sınıfından genişletilebilir.

Override anotasyonunu (annotation) görüyorsunuz. Anotasyonlar Java 1.5′ten sonra gelen bir özelliktir. Buradaki Override anotasyonu, Word ve PDF’te bulunan print metodlarının ata sınıfın (Document) print metodunun üzerine yazıldığı anlamına gelir.

Burada dikkat ederseniz PDF ve Word sınıfları Document nesnesinden genişletildi. Yani PDF ve Word sınıfının nesneleri aynı zamanda Document sınıfının da bir nesnesi haline geldi. Bu yüzden Printer sınıfını aşağıdaki şekilde değiştirebiliriz.

Printer sınıfı artık aynı işi yapan tek bir print metoduna sahip oldu. Parametre olarak da Document nesnesi alıyor. Daha iyi anlayabilmeniz için Document, Word ve PDF sınıflarının print metodlarına println ekleyelim.

println statik metodunu eklememin sebebi sınıfların davranışını görebilmeniz içindir. Şimdi Printer sınıfının davranışını görelim.

Printer sınıfının davranışını görüntüleyebilmek için TestPrinter isimli bir sınıf ekledim. Bu sınıf statik main metodunu da içeriyor. Bu sayede çıktıya bakarak sınıfların davranışlarını inceleyebiliriz.

4. satır da Printer sınfının bir nesnesi üretiliyor.
6. satırda printer nesnesinin print metoduna yeni bir döküman sınıfı parametre olarak gönderiliyor ve ekranda “Döküman yazdırıldı.” yazısını görüyoruz. Printer sınıfı Document nesnesinin print metodunu çağırdığı için çıktımızda bu yazıyı gördük.
8. satırda ise Printer sınıfının print metoduna PDF nesnesi gönderdik. Bu sefer de ekranda “PDF dökümanı yazdırıldı.” yazısını görüyoruz. Kısacası Document sınıfında tanımlanan print metodunu PDF için davranışını değiştirmiş olduk. Yani parametre olarak Document(PDF yerine) nesnesi almamıza rağmen PDF içinde tanımlanan metod çağrılmış oldu.Aynı şey 10. satırdaki Word nesnesi için de geçerli. print metodu Word için farklı PDF için farklı bir şekilde işlev sağladı. İşte buna polimorfizm denir.

Şimdi gelelim Presentation sınıfını eklemeye. Çok basit bir şekilde sadece Presentation sınıfı eklememiz yeterli olacaktır.

Printer sınfında herhangi bir değişiklik yapmamıza gerek yok. Çünkü Printer sınıfı yeni eklediğimiz Presentation belgesini de yazdırabilecek yeteneğe sahip.

super Anahtar Kelimesi

Örneğimize bakarsak PDF sınıfı Document‘in print metodunun üzerine kendi print metodunu yazarak (ezerek) davranışını değiştirmiş oldu ve Document sınıfında tanımlanan print metodunun davranışını iptal etti. Peki PDF sınıfı atasından (Document) aldığı print metodunu kullanmak isterse ne yapmalıyız? İşte burda super anahtar kelimesini kullanabiliriz. PDF sınıfını aşağıdaki şekilde değiştirelim.

super anahtar kelimesi ile ata sınıfın özelliklerine erişmemizi sağlar. Printer sınıfına PDF‘in nesnesini gönderdiğimiz de çıktı olarak hem “Döküman yazdırıldı.” hem de “PDF dökümanı yazdırıldı.” alırız. Bunu sağlayan PDF‘in print metodu içerisinde kullandığımız super.print() metodu sayesindedir. Örneğin eğer ata sınıfın yapılandırıcı (constructor)  metodunu kullanmak istersek super() metodunu kullanabiliriz. Fakat ata sınıfta tanımlanan değişken ve metodların private olmaması gerekmektedir.

Bu yazımda polimorfizmi anlatmaya çalıştım. Umarım faydalı olmuştur.

İyi çalışmalar