Upcasting ve Downcasting
Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 30 / 87.
Önceki derste, üst türdeki bir değişkenin bir alt nesneyi nasıl tutabildiğini gördünüz: Animal myPet = new Dog(). Bu atama upcasting olarak adlandırılır ve bir Dog her zaman bir Animal olduğu için otomatik olarak gerçekleşir.
Upcasting kalıtım hiyerarşisinde yukarı doğru hareket eder. Örtüktür ve her zaman güvenlidir:
Dog dog = new Dog();
Animal animal = dog; // Upcasting - otomatikUpcast yaptığınızda, yalnızca üst sınıfta tanımlanan metotlara erişebilirsiniz. Nesne temelde hala bir Dog olsa bile, alt sınıfa özgü metotlar gizli hale gelir.
Downcasting, bir üst sınıf (parent) referansını tekrar bir alt sınıf (child) türüne dönüştürerek ters yönde ilerler. Bu, her zaman güvenli olmadığı için açık bir tür dönüşümü (explicit cast) gerektirir:
Animal animal = new Dog(); // Upcasting
Dog dog = (Dog) animal; // Downcasting - açık tür dönüşümü gereklidir
dog.bark(); // Artık Dog metotlarına erişebilirizDowncasting risklidir. Eğer nesne aslında dönüştürmeye çalıştığınız türde değilse, Java çalışma zamanında bir ClassCastException fırlatır:
Animal animal = new Cat();
Dog dog = (Dog) animal; // Derlenir, ancak çalışma zamanında çöker!Derleyici bu hatayı yakalayamaz çünkü yalnızca bildirilen türleri görür. Gerçek nesne türü yalnızca program çalıştığında bilinir. Bir sonraki derste, downcasting işleminden önce bir nesnenin türünü güvenli bir şekilde nasıl kontrol edeceğinizi öğreneceksiniz.
Görev
KolayHem yukarı doğru dönüştürme (upcasting) hem de aşağı doğru dönüştürme (downcasting) işlemlerini uygulamalı olarak gösteren bir medya oynatıcı sistemi oluşturalım. Bir medya türleri hiyerarşisi oluşturacak ve üst sınıf ile alt sınıf referansları arasında dönüşüm yapma pratiği yapacaksınız.
Kodunuzu dört dosya halinde düzenleyeceksiniz:
Media.java: Tüm medya türlerinin paylaştığı temel sınıfı oluşturun. Her medya öğesinin birtitlealanı (String) vardır. Bunu başlatmak için bir yapıcı (constructor), bir getter metodugetTitle()ve şu çıktıyı veren birplay()metodu ekleyin:Playing: [title]Song.java: Media sınıfını genişleten bir sınıf oluşturun. Şarkıların ek birartistalanı (String) vardır. Üst sınıf başlatması içinsuperkullanın.play()metodunu şu çıktıyı verecek şekilde geçersiz kılın (override):Playing song: [title] by [artist]. Şu çıktıyı veren birshowArtist()metodu ekleyin:Artist: [artist]Podcast.java: Media sınıfını genişleten başka bir sınıf oluşturun. Podcast'lerin birepisodealanı (int) vardır.play()metodunu şu çıktıyı verecek şekilde geçersiz kılın:Playing podcast: [title] - Episode [episode]. Şu çıktıyı veren birshowEpisode()metodu ekleyin:Episode: [episode]Main.java: Medya türlerinizle yukarı doğru dönüştürme ve aşağı doğru dönüştürme işlemlerini gösterin. Dört girdi alacaksınız: bir şarkı adı, bir sanatçı adı, bir podcast adı ve bir bölüm numarası.Önce, bir Song oluşturun ve onu bir Media referansına yukarı doğru dönüştürün (upcast). Çalışma zamanı polimorfizmini (run-time polymorphism) iş başında görmek için bu referans üzerinde
play()metodunu çağırın.Ardından, bu Media referansını tekrar bir Song'a aşağı doğru dönüştürün (downcast) ve alt sınıfa özgü metoda erişmek için
showArtist()metodunu çağırın.Sonra, bir Podcast oluşturun ve onu bir Media referansına yukarı doğru dönüştürün. Bu referans üzerinde
play()metodunu çağırın.Son olarak, bu Media referansını tekrar bir Podcast'e aşağı doğru dönüştürün ve
showEpisode()metodunu çağırın.
Dört girdi alacaksınız: şarkı adı (String), sanatçı adı (String), podcast adı (String) ve bölüm numarası (int).
Çıktınız dört satır göstermelidir - ikisi şarkı için (oynatma çıktısı ve sanatçı bilgisi) ve ikisi podcast için (oynatma çıktısı ve bölüm bilgisi). Yukarı doğru dönüştürmenin farklı medya türlerine tek tip davranmanıza nasıl olanak tanıdığını, aşağı doğru dönüştürmenin ise onların benzersiz özelliklerine erişmenizi nasıl sağladığını fark edin!
Kopya kağıdı
Java'da, upcasting kalıtım hiyerarşisinde yukarı doğru hareket eder ve otomatik olarak gerçekleşir. Bir çocuk nesne, ebeveyn türündeki bir değişkene atanabilir:
Dog dog = new Dog();
Animal animal = dog; // Upcasting - otomatikUpcasting yaptığınızda, nesne hala temelinde çocuk türünde olsa bile, yalnızca ebeveyn sınıfında tanımlanan metotlara erişebilirsiniz.
Downcasting, bir ebeveyn referansını tekrar çocuk türüne dönüştürür. Açık bir dönüştürme gerektirir:
Animal animal = new Dog(); // Upcasting
Dog dog = (Dog) animal; // Downcasting - açık dönüştürme gerekir
dog.bark(); // Artık Dog metotlarına erişebilirizDowncasting risklidir. Eğer nesne aslında dönüştürmeye çalıştığınız türde değilse, Java çalışma zamanında bir ClassCastException fırlatır:
Animal animal = new Cat();
Dog dog = (Dog) animal; // Derlenir, ancak çalışma zamanında çöker!Derleyici bu hatayı yakalayamaz çünkü yalnızca bildirilen türleri görür. Gerçek nesne türü yalnızca program çalıştığında bilinir.
Kendin dene
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Girdileri oku
String songTitle = scanner.nextLine();
String artistName = scanner.nextLine();
String podcastTitle = scanner.nextLine();
int episodeNumber = scanner.nextInt();
// TODO: Bir Song oluşturun ve onu bir Media referansına upcast edin
// TODO: Media referansı üzerinde play() metodunu çağırın (polimorfizmi gösterir)
// TODO: Media referansını tekrar Song sınıfına downcast edin
// TODO: Song referansı üzerinde showArtist() metodunu çağırın
// TODO: Bir Podcast oluşturun ve onu bir Media referansına upcast edin
// TODO: Media referansı üzerinde play() metodunu çağırın
// TODO: Media referansını tekrar Podcast sınıfına downcast edin
// TODO: Podcast referansı üzerinde showEpisode() metodunu çağırın
}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesnelerthis Anahtar KelimesiMetotlarAlanlar (Öznitelikler)Yapıcı MetotYapıcı Metot Aşırı YüklemeÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (extends)super Anahtar KelimesiMetot Geçersiz Kılma (@Override)Yapıcı Metot ZincirlemeObject SınıfıTekli ve Çok Seviyeli KalıtımNeden Çoklu Sınıf Kalıtımı Yok?Özet - Çalışan Hiyerarşisi7Özel Metotlar ve Object Sınıfı
toString() Metoduequals() ve hashCode()clone() MetoducompareTo() ve ComparableComparator ArayüzüÖzet - Özel Sıralama2Erişim Belirleyiciler ve Kapsülleme
Erişim Seviyelerine Genel BakışGetter ve Setter MetotlarıBilgi Gizlemefinal Anahtar KelimesiÖzet - Banka Hesabı Yöneticisi5Polimorfizm
Metot Aşırı Yükleme TemelleriMetot Geçersiz Kılma (Çalışma Zamanı)Upcasting ve Downcastinginstanceof OperatörüSoyut Sınıflar ve MetotlarÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımAgregasyon vs KompozisyonDahili, Yuvalanmış ve Anonim SınıflarEnum'lar ve Enum MetotlarıRecords (Java 16+)Sealed Classes (Java 17+)11Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıBuilder KalıbıObserver KalıbıStrategy Kalıbı14Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi3Sınıf Özellikleri ve Statik Üyeler
Instance ve Statik DeğişkenlerStatik MetotlarStatik BloklarSabitler (static final)Özet - Sayaç ve Utility6Arayüzler ve Soyut Sınıflar
Arayüzlere GirişArayüzleri UygulamaÇoklu Arayüz UygulamaArayüzlerde Default ve StaticSoyut Sınıflar ve ArayüzlerFonksiyonel ArayüzlerÖzet - Ödeme Sistemi9Generics
Generics'e GirişGeneric SınıflarGeneric MetotlarSınırlandırılmış Tip ParametreleriWildcard'lar (?, extends, super)Özet - Generic Container12Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit KalıbıYineleyici Kalıbı