ÖNEMLİ : Kendim için aldığım notlar. Umarım size de bir faydası olur. Kullanılan her bir makale referans olarak eklenmiştir.
Java’da Kalıtım(inheritance) ve Java’da Polimorfizm Serisi
- Java’da Polimorfizm 1 - Amaç?
- Java’da Polimorfizm 2 - İzlenecek Kurallar Nelerdir?
- Java’da Polimorfizm 3 - Casting
- Java’da Polimorfizm 4.1 - Statik ve Dinamik Bağlanma 1
- Java’da Polimorfizm 4.2 - Statik ve Dinamik Bağlanma 2
- Java’da Polimorfizm 4.3 - Dinamik Bağlanma Örnek
- Java’da Polimorfizm 5 - Soyut(Abstract) Sınıflar ve Arayüzler(Interfaces)
Genel Bakış
Katıldığım online bir etkinlikte object-oriented nedir şeklinde sorulan bir soruya Robert C. Martin şu şekilde yanıt vermişti.
“A language is object-oriented if it supports dynamic polymorphism” (“Bir dil, dinamik polimorfizmi destekliyorsa nesne yönelimlidir”)
Kısa ve öz bir tanım.
Anlaşılacağı üzere polimorfizm nesne yönelimli bir dilin merkezindedir. Bu bölümde ise derleme zamanı ve çalışma zamanı kurallarına odaklanacağız. Ve bunu bir kez anladığınızda, polimorfizmin çalışma mantığını çok iyi anlayacağınızı temin ederim.
Derleyici gibi düşün, çalışma zamanı ortamı gibi davran (Rick Ord)
Bu sözün aslında altında yatan mantık çok açıktır. Çünkü bir kodu her çalıştırdığımızda gerçekleşen iki şey vardır. Birincisi, bir derleyicinin yazdığınız kodu yorumlaması gerektiğidir. İkinci şey ise, çalışma zamanı ortamı bu yorumlanan alıntıyı çalıştırır. Polimorfizm hakkında düşüneceksek şayet bunları göz önüne almamız gerekmektedir. O halde, polimorfizm söz konusu olduğunda derleme zamanı kurallarına ve çalışma zamanı kurallarına bakarak devam edelim.
Derleme Zamanı Kuralları(Compile-time Decision)
-
Derleyici SADECE referans tipini bilir: (yani derleyici nesnenin çalışma zamanı tipini bilmez. Derleyicinin amacı, daha sonra çalışma zamanında yürütülecek olan bir yöntem imzası çıkarmaktır.)
1 2
Person s = new Student("Hasan", 1111); s.toString();
Yukarıdaki örnekte bir adet Person, bir adet de Student sınıfımız bulunmaktadır. Görüleceği üzere Person sınıf tipinde s referansımız, Student nesnesine işaret ediyor. Planımız her ne kadar Student nesnesinde
toString
yöntemini çağırmak gibi görünse de(aslında bir bütün olarak baktığımızda öyle!), javanın kodu bu şekilde yorumlamadığını bilmemizde yarar var. Java kurallarını derleme ve çalışma zamanı olarak ikiye ayırır. Kurala göre de derleyicinin sadece Person referansını bildiğini unutmayalım. Yani derleme zamanında javanın bu koddan algıladığı tek şey s referansının bir Person olduğudur. -
Derleyici metot çağrıları için SADECE referans tipinin sınıfına bakar: s referansı ile
toString
‘i çağırmayı denediğinizde, java derleme zamanında ilk olarak Person sınıfına bakacak ve butoString
yöntemini bulacaktır. -
Derleyici bir yöntem imzası yayımlar: Derleyicinin bir diğer amacı ise daha sonra çalışma zamanında yürütülecek olan bir yöntem imzası çıkarmaktır. Yani parametresiz bir toString yöntem imzası derleyici tarafından daha sonra çalışma zamanında yürütülmek üzere yayımlanır.
Çalışma Zamanı Kuralları(Runtime Decision)
- Çalışma zamanında, ilgili yöntemi bulmak için java, nesnenin çalışma zamanı türünü izler
-
Derleme zamanında yayımlanan yöntem imzasını gerçek çalışma zamanı sınıfındaki uygun yöntemle eşleştirir: Yukarıdaki örnekten yola çıkarsak,
s.toString
yapmaya çalıştığımızda java, artık çalışma zamanında s‘in aslında bir Student nesnesi olduğunu bilir ve bu metodu ilk bu sınıfın içinde arar. Yukarıdaki koddan yola çıkarsak, java Student sınıfındatoString
yöntemini bulacak ve çalışma zamanında çalıştıracaktır.ÖNEMLİ NOT : Buraya kadar olanlar ilgili yöntem(yani
toString
metodunu kastediyorum) geçersiz kılınmışsa gerçekleşecek şeylerdir. Çünkü ilgili yöntem geçersiz kılınmışsa, polimorfizm gereği doğrudan geçersiz kılınan yöntem çalıştırılır. Yani bu örnekte yöntemin geçersiz kılındığını görüyoruz. -
Peki ilgili yöntem geçersiz kılınmamışsa ne olur? Bu durumda ise java çalışma zamanı sınıfında uygun bir yöntem bulamadığı için referans tipinin sınıfındaki yöntemle eşleşir. Bu kısım çok önemlidir. Farzedelim ki yukarıdaki örnek şu şekilde olsaydı(Student sınıfına odaklanmanızı istiyorum. Dikkat ederseniz
toString
metodu override edilmemiş)s.toString
yazarak metodu çağırmaya çalıştığımızda, Person sınıfındakitoString
metodu çalışacaktır.
Aslında polimorfizm, derleme zamanı ve çalışma zamanı polimorfizmi olarak ikiye ayırabiliriz. Derleme zamanında alınan kararlar sonucu gerçekleşen bağlanmalara statik/erken bağlanma(static or early binding), çalışma zamanında alınan kararlar sonucu gerçekleşen bağlanmalara da dinamik/geç bağlanma(dynamic or late binding) denir. Bununla ilgili aslında ayrı bir bölüm açmayı planlıyorum. Çünkü burada bahsedilenlerin dışında da değineceğim bilgiler var.
Şimdi yukarıdaki kuralları düşünerek aşağıdaki soruya cevap bulmaya çalışalım.
Örnek
Bu sefer s referansı ile getSID() metoduna ulaşmaya çalışacağız. Yukarıda yazdığım için tekrardan Student ve Person sınıflarını yazma gereği duymadım. Göreceğiniz üzere bu metot Student sınıfının içinde yer almaktadır. Sizce bu kod çalışır mı?
1
2
Person s = new Student("Hasan", 1234);
s.getSID();
Aslında ilk bakışta kodun çalışacağını düşünebiliriz. Ama çalışma zamanı dışında bir de derleme zamanı kararlarına uymamız gerekmektedir. Sırayla ilerleyecek olursak kodun çalışması için ilk önce derleme zamanı kurallarını karşılaması gerekmektedir. Koda tekrar bakacak olursak, derleyici yalnızca Person içindeki yöntemleri bilecektir. Çünkü derleyiciye göre s bir Person referansıdır. Dolayısıyla, derleyici Person sınıfında getSID
yöntemini bulmaya çalışacaktır. Fakat bu yöntemin Person sınıfında olmadığını biliyoruz. Bu sebepten ötürü bir derleme hatası alırız. Yani kodun çalışma zamanına geçme şansı olmayacaktır.
Yalnız koda baktığımızda bu metodun Student sınıfında bulunduğunu biliyoruz. Peki bizim bu bildiğimizi derleyicinin bilmesini nasıl sağlarız. Bunun yöntemi casting‘dir. Bir sonraki ders bu konu üzerine konuşacağız.
Özet
Java’da polimorfizm konusundan bahsederken sıklıkla derleme ve çalışma zamanı kararlarından bahsettik. Aslında polimorfizmi tanımsal olarak rahatlıkla ikiye ayırabiliriz.
- Statik veya derleme zamanı polimorfizmi
- Dinamik veya çalışma zamanı polimorfizmi
Anlaşılacağı üzere statik polimorfizm derleme zamanında gerçekleşirken, dinamik polimorfizm çalışma zamanında gerçekleşir.
Referanslar
- Chapter 5. Conversions and Promotions
- Polymorphism (biology)
- Polymorphism (computer science)
- Static vs. Dynamic Type
- Dynamic typing vs. static typing
- Static Typing vs Dynamic Typing
- Difference between Dynamic and Static type assignments in Java
- New JDK 7 Feature: Support for Dynamically Typed Languages in the Java Virtual Machine
- Dynamic Class Loading Example
- Dynamic Class Loading
- Java Reflection - Dynamic Class Loading and Reloading
- Fully Dynamic Classes With ASM
- Polymorphism
- Object Oriented Programming in Java
- Java: Is method name/signature resolution done statically (compile-time)?