instanceof Operatörü
Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 31 / 87.
Önceki ders, nesne aslında dönüştürmeye çalıştığınız türde değilse aşağı doğru tür dönüştürmenin (downcasting) bir ClassCastException ile başarısız olabileceğini gösterdi. instanceof operatörü, dönüştürme yapmadan önce bir nesnenin türünü kontrol etmenize izin vererek bu sorunu çözer.
Sözdizimi basittir: object instanceof ClassName, nesne o sınıfın (veya alt sınıflarından herhangi birinin) bir örneği ise true döndürür:
Animal animal = new Dog();
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark(); // Dog'a özgü metotları çağırmak güvenlidir
}Bu kontrol, tür dönüşümünün başarılı olmasını sağlayarak çalışma zamanı hatalarını önler. Operatör ayrıca hiyerarşideki üst türler için de true değerini döndürür:
Dog dog = new Dog();
System.out.println(dog instanceof Dog); // true
System.out.println(dog instanceof Animal); // true
System.out.println(dog instanceof Object); // trueJava 16'dan beri, desen eşleştirme (pattern matching) kullanarak kontrol ve tür dönüşümü işlemlerini tek bir adımda birleştirebilirsiniz:
if (animal instanceof Dog dog) {
dog.bark(); // 'dog' zaten dönüştürülmüştür ve kullanıma hazırdır
}Bu daha temiz sözdizimi, ayrı bir tür dönüştürme (cast) satırını ortadan kaldırır. instanceof operatörünün null ile test edildiğinde false döndürdüğünü unutmayın; bu nedenle ayrı bir null kontrolüne ihtiyacınız yoktur.
Görev
KolayFarklı araç türlerini güvenli bir şekilde tanımlamak ve işlemek için instanceof operatörünü kullanan bir araç muayene sistemi oluşturalım. Bir araç hiyerarşisi oluşturacak ve her aracın özel özelliklerine erişmeden önce gerçek türünü kontrol eden bir kod yazacaksınız.
Kodunuzu dört dosya halinde düzenleyeceksiniz:
Vehicle.java: Tüm araçların paylaştığı temel sınıfı oluşturun. Her aracın birmodelalanı (String) vardır. Bunu başlatmak için bir yapıcı (constructor), bir getter metodugetModel()ve şu çıktıyı veren birinspect()metodu ekleyin:"Inspecting vehicle: " + modelCar.java: Vehicle sınıfını genişleten bir sınıf oluşturun. Arabaların ek birnumDoorsalanı (int) vardır. Üst sınıf başlatması içinsuperkullanın. Şu çıktıyı veren bircheckDoors()metodu ekleyin:getModel() + " has " + numDoors + " doors"Motorcycle.java: Vehicle sınıfını genişleten başka bir sınıf oluşturun. Motosikletlerin birhasSidecaralanı (boolean) vardır. Boolean değerine bağlı olarakgetModel() + " has a sidecar"veyagetModel() + " has no sidecar"yazdıran bircheckSidecar()metodu ekleyin.Main.java: İşteinstanceofoperatörünün vazgeçilmez olduğu yer burası! Dört girdi alacaksınız: bir araba modeli, kapı sayısı, bir motosiklet modeli ve bir sepeti (sidecar) olup olmadığı (true/false).Bir Car ve bir Motorcycle içeren bir
Vehiclereferans dizisi oluşturun. Ardından dizi boyunca döngü kurun ve her araç için:- Temel
inspect()metodunu çağırın - Bir Car olup olmadığını kontrol etmek için
instanceofkullanın - eğer öyleyse, güvenli bir şekilde alt türe dönüştürün (downcast) vecheckDoors()metodunu çağırın - Bir Motorcycle olup olmadığını kontrol etmek için
instanceofkullanın - eğer öyleyse, güvenli bir şekilde alt türe dönüştürün (downcast) vecheckSidecar()metodunu çağırın
- Temel
Dört girdi alacaksınız: araba modeli (String), kapı sayısı (int), motosiklet modeli (String) ve sepeti olup olmadığı (boolean).
Çıktınız dört satır göstermelidir - her araç için muayene mesajını ve ardından türe özgü kontrolünü göreceksiniz. instanceof operatörü, Car metodlarını yalnızca gerçek Car nesnelerinde ve Motorcycle metodlarını yalnızca gerçek Motorcycle nesnelerinde çağırmanızı sağlayarak herhangi bir ClassCastException hatasını önler!
Kopya kağıdı
instanceof operatörü, bir nesnenin tür dönüşümü (casting) yapılmadan önce belirli bir sınıfın örneği olup olmadığını kontrol eder:
Animal animal = new Dog();
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark(); // Dog sınıfına özgü metotları çağırmak güvenlidir
}Operatör, nesnenin kendi sınıfı ve hiyerarşideki tüm üst sınıfları için true değerini döndürür:
Dog dog = new Dog();
System.out.println(dog instanceof Dog); // true
System.out.println(dog instanceof Animal); // true
System.out.println(dog instanceof Object); // trueJava 16'dan beri, desen eşleştirme (pattern matching) kontrol ve tür dönüşümü işlemlerini tek bir adımda birleştirir:
if (animal instanceof Dog dog) {
dog.bark(); // 'dog' değişkeni zaten dönüştürülmüştür ve kullanıma hazırdır
}instanceof operatörü, null değerine karşı test edildiğinde false döndürür, bu da ayrı null kontrolleri yapma ihtiyacını ortadan kaldırır.
Kendin dene
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Girdileri oku
String carModel = scanner.nextLine();
int numDoors = Integer.parseInt(scanner.nextLine());
String motorcycleModel = scanner.nextLine();
boolean hasSidecar = Boolean.parseBoolean(scanner.nextLine());
// TODO: carModel ve numDoors ile bir Car nesnesi oluşturun
// TODO: motorcycleModel ve hasSidecar ile bir Motorcycle nesnesi oluşturun
// TODO: Car ve Motorcycle içeren bir Vehicle referans dizisi oluşturun
// TODO: Dizi boyunca döngü kurun ve her araç için:
// 1. inspect() metodunu çağırın
// 2. Bir Car olup olmadığını kontrol etmek için instanceof kullanın, ardından downcast yapın ve checkDoors() metodunu çağırın
// 3. Bir Motorcycle olup olmadığını kontrol etmek için instanceof kullanın, ardından downcast yapın ve checkSidecar() 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ı