Polimorfizm ve Dinamik Bağlama — Kararı Kim Veriyor?
Önce şunu oku: Kalıtım ve Kompozisyon — Kimin İç Ayrıntısına Bağlısın?
30 saniyede özet
Aynı çağrı nesneye göre farklı iş yapabilir; buna polimorfizm denir. Ama her karar çalışırken verilmez: aşırı yükleme, static metotlar ve alanlar derlerken sabitlenir. İkisini karıştırmak sessiz hatalar doğurur.
İki noktanın eşit olup olmadığını söyleyen bir equals yazdın, ama iki eşit nokta bir kümeye ikisi birden girdi. Metot doğru, karşılaştırma doğru — ama hiç çağrılmıyor. Sebep: yazdığın şey bir override değil, bir overload.
-
Bayt: İki eşit nokta kümeye ikisi birden girdi! equals'ım doğru ama hiç çağrılmıyor.
-
Sen: Nasıl yani, metot orada duruyor.
-
Bayt: Duruyor. Ama belki eskisini değiştirmedin, yanına yeni bir metot yazdın.
-
Bayt: Menüden seçim mi, vardiyadaki kişi mi? Kararı kimin verdiğine bakalım.
Aynı çağrı, farklı davranış
polimorfizmAynı çağrının, nesnenin gerçek tipine göre farklı davranış üretmesi. Java'da override edilmiş örnek metotlarıyla sağlanır.Sözlükte gör →, aynı çağrının karşısındaki nesneye göre farklı iş yapmasıdır. shape.area() yazan kod, karşısında daire mi kare mi olduğunu bilmez; alanı doğru hesaplamak nesnenin kendi işidir.
Java bunu dinamik bağlamaÇağrılacak metodun sürümünün derleme anında değil, çalışma anında nesnenin gerçek sınıfına bakılarak seçilmesi.Sözlükte gör → ile yapar. Program çalışırken JVM nesnenin gerçek sınıfına bakar ve o sınıfın yazdığı sürümü çağırır.
Kafam karıştı, daha basit anlat
Bir kumandada tek bir “aç” tuşu var. Televizyona basarsan ekran, klimaya basarsan fan açılır. Tuş aynı, işi yapan karşısındaki cihaz.
`Animal a = new Dog(); a.sound();` — Dog, sound()'u override ediyor. Hangi sürüm çalışır?
@Override anotasyonu ne işe yarar?
Kim, ne zaman karar veriyor?
describe(Object) ve describe(String) var. Object value = "merhaba"; describe(value) hangisini çağırır? Cevabı göster
describe(Object). overloadingAynı adlı, farklı parametre listeli metotlar. Hangisinin çağrılacağına derleyici, argümanların bildirilen tiplerine bakarak karar verir.Sözlükte gör → seçimi derleme anında, argümanın bildirilen tipine göre yapılır. Nesnenin String olması fark etmez.
Adım adım oku
- describe(value) derlenirken derleyici değişkenin yazılı tipine bakar: Object. Menüden describe(Object) seçilir.
- Çalışırken nesnenin aslında bir String olduğu anlaşılır, ama overload seçimi çoktan yapılmıştır; değişmez.
- s.area() ise bir override'dır: JVM çalışırken nesnenin gerçek sınıfına bakar ve Circle'ın area'sını çağırır.
- Özet: overload derleme anında değişkenin tipine göre, override çalışma anında nesnenin sınıfına göre seçilir.
| Erişim | Karar ne zaman | Neye göre |
|---|---|---|
| Override edilmiş örnek metodu | Çalışma anı | Nesnenin gerçek sınıfı |
| Aşırı yüklenmiş metot | Derleme anı | Argümanların bildirilen tipi |
| Static metot | Derleme anı | Değişkenin bildirilen tipi |
| Alan | Derleme anı | Değişkenin bildirilen tipi |
Tablodaki dört satırdan yalnızca ilki çalışırken karar verir. Geri kalan her şeyi derleyici, sen programı çalıştırmadan önce sabitler.
Bankada ikisi de karşına çıkar. Havale masrafı kanala göre değişir; override sayesinde servis hangi kanalda olduğunu bilmeden doğru masrafı alır. Bloke IBAN listesinde ise overload edilmiş bir equals, bloke hesaba para gönderilmesine göz yumar.
Derinleş · Havale masrafı ve bloke IBAN: override mı, overload mı? 4 dosya · ~100 satır · ilk okumada atlayabilirsin
Kafam karıştı, daha basit anlat
Program çalışırken yalnızca bir karar verilir: nesnenin gerçek sınıfına göre hangi metodun çalışacağı. Aynı isimli metotlardan hangisinin seçileceğine derleyici önceden karar verir.
Program ne yazdırır?
`Animal a = new Dog();` ile yapılan her erişim için seçim ne zaman yapılır?
Kendin gör
Polimorfizm — hangi sürüm, ne zaman seçilir?
Tohum 709163class Animal { String name = "hayvan"; Animal() { describe(); } void describe() { } String sound() { return "..."; } static String kind() { return "Animal"; }}class Dog extends Animal { String name = "köpek"; private String label = "Karabaş"; @Override void describe() { System.out.println(label.length()); } @Override String sound() { return "Hav"; } static String kind() { return "Dog"; }}class Printer { String print(Animal x) { return "print(Animal)"; } String print(Dog x) { return "print(Dog)"; }} Animal a = new Dog();System.out.println(a.sound());- Oynat ya da adımla.
Şu an ne oldu?
Animal a = new Dog();
a.sound() çağrılacak. Nesne her durumda bir Dog.
Görevler0/3
Animal değişkeniyle Dog'un sürümünü çalıştıraçık
İpucu
Seçimi nesnenin gerçek sınıfı yapan tek tür çağrı hangisi?
Nesne Dog olduğu hâlde Animal'ın sürümünü çalıştıraçık
İpucu
Derleme anında bağlanan üç şey var.
Nesne daha kurulmadan alt sınıfın metodunu çalıştıraçık
İpucu
Taban sınıfın constructor'ı override edilebilir bir metot çağırıyor.
Olay günlüğü (0)
Henüz olay yok. Oynat veya adımla.
- Varsayılanla oynat. Animal değişkeni, Dog nesnesi: “Hav”.
- “Static metot” seç. Aynı nesne, “Animal” — derleyici seçti.
- “Alan” seç, sonra değişkeni Dog yap. Farklı değişken, farklı alan.
- “Constructor’dan…” seç. NullPointerException.
`Animal a = new Dog(); System.out.println(a.name);` — iki sınıfta da `name` alanı var. Ne yazdırılır ve neden?
Satır satır: constructor’daki tuzak
Nesne bitmeden alt sınıfın kodu
class Animal { Animal() { describe(); } void describe() { }}class Dog extends Animal { private String label = "Karabaş"; @Override void describe() { System.out.println(label.length()); }} new Dog();Debug
JVM Dog nesnesi için bellek ayrıldı; bütün alanlar varsayılan değerinde.
- label
- = null
Sol/sağ ok tuşlarıyla da gezebilirsin.
Constructor’dan, alt sınıfın değiştirebileceği bir metodu çağırma. Alt sınıfın alanları henüz hazır değilken onun kodu çalışır. Yardımcı metodu private, final ya da static yap ki değiştirilemesin.
Kafam karıştı, daha basit anlat
Ev daha kurulmadan içine eşya taşımaya benzer. Üst sınıfın constructor’ı alt sınıfın metodunu çağırırsa, alt sınıfın alanları henüz boştur.
Animal'ın constructor'ı override edilebilir `describe()` metodunu çağırıyor. Dog bu metodu override edip kendi `label` alanını okuyor. `new Dog()` ne olur?
Tuzaklar
equals(Point) yazmak. Parametre tipi farklı olduğu için bu, Object.equals(Object)’in yerine geçmez; yanına ikinci bir metot ekler. Koleksiyonlar senin metodunu hiç çağırmaz.
@Override’ı yazmamak. Bu etiket “ben bir metodun yerine geçiyorum” demektir; yanılıyorsan derleyici hemen uyarır.
Uzun instanceof zincirleri. Nesneye tipini sormak yerine davranışı sınıfların kendisine taşı; bütün durumları derleyiciye kontrol ettirmek istersen sealed + switch kullan.
Aynı adlı alanlar. Alt sınıfta aynı adla bir alan tanımlamak üsttekini değiştirmez, ikinci bir alan yaratır. Hangisini okuduğun, değişkenin tipine bağlıdır.
İki eşit Point bir HashSet'e konuyor ve set iki eleman içeriyor. `set.contains(new Point(1, 2))` de false dönüyor. Hangi satır?
Kendini sına
Override edilen bir metodun hangi sürümünün çalışacağına çalışma anında karar verilir.
Bir metotta `if (shape instanceof Circle) ... else if (shape instanceof Square) ...` zinciri var ve her yeni şekil eklendiğinde buraya dal ekleniyor. Polimorfizmle nasıl düzeltilir?
Aklında kalacak üç şey
- 1 Override edilmiş bir metotta hangi kodun çalışacağını nesnenin gerçek sınıfı seçer. Değişkenin tipi yalnızca çağrının yazılabilir olup olmadığını belirler.
- 2 Aşırı yükleme, static metotlar ve alanlar derleme anında, yazılan tipe göre bağlanır. Bunlar polimorfik değildir.
- 3 Constructor içinden override edilebilir bir metot çağırmak, alt sınıfın kodunu alanları hazır olmadan çalıştırır.
3 kart sonraki derste seni bekliyor
Bu dersin üstüne kurulanlar
Bunlar bu dersi temel alıyor; hazır olduğunda devam edebilirsin.
- Nesne Yönelimli ProgramlamaInterface ve Abstract Class — Rol mü, İskelet mi?Bir sınıf neden yalnızca tek bir sınıftan türeyebilir ama istediği kadar rol üstlenebilir?Derse git
- Nesne Yönelimli ProgramlamaSoyutlama ve Dört Sütun — Hangi Değişikliğe Hangisi Yardım Eder?Kapsülleme, soyutlama, kalıtım, polimorfizm. Dördü de aynı soruya cevap: bir şey değişince kaç dosya değişir?Derse git
- Core Java & EşzamanlılıkSınıf Yükleme ve JIT — Uygulama Neden Isınır?Yeni sürümü yayına aldın: ilk dakikalar yavaş, sonra her şey hızlanıyor. Neden?Derse git