Wildcard'lar (?, extends, super)
Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 57 / 87.
bounded tür parametreleri generic türleri belirli türlerle sınırlar, ancak mevcut generic türlerle çalışırken tam tür parametresini bilmiyorsanız veya bunu önemsemiyorsanız ne olur? İşte burada wildcards devreye girer.
sınırsız joker karakter ?, bilinmeyen bir türü temsil eder. Herhangi bir parametreli türü kabul etmek istediğinizde kullanışlıdır:
public static void printList(List<?> list) {
for (Object item : list) {
System.out.println(item);
}
}
printList(new ArrayList<String>()); // Çalışır
printList(new ArrayList<Integer>()); // ÇalışırÜst sınırlı joker karakter ? extends Type, belirtilen türü veya onun alt sınıflarından herhangi birini kabul eder. Genel bir yapıdan okumanız gerektiğinde kullanın:
public static double sumNumbers(List<? extends Number> numbers) {
double sum = 0;
for (Number n : numbers) {
sum += n.doubleValue();
}
return sum;
}
sumNumbers(Arrays.asList(1, 2, 3)); // Integer listesi
sumNumbers(Arrays.asList(1.5, 2.5)); // Double listesiAlt sınırlandırılmış joker karakter ? super Type, belirtilen türü veya onun herhangi bir üst sınıfını kabul eder. Genel bir yapıya yazmanız gerektiğinde bunu kullanın:
public static void addIntegers(List<? super Integer> list) {
list.add(1);
list.add(2);
}
List<Number> numbers = new ArrayList<>();
addIntegers(numbers); // Çalışır - Number, Integer'ın bir üst tipidirYararlı bir kural: yalnızca okuma (üretici) yaptığında extends, yalnızca yazma (tüketici) yaptığında super kullan. Bu, PECS ilkesi olarak bilinir: Producer Extends, Consumer Super.
Görev
KolayHer üç joker karakter türünü de gösteren bir hayvanat bahçesi besleme sistemi oluşturalım! Bir hayvan ve yiyecek hiyerarşisi oluşturacak, ardından farklı besleme senaryolarını ele almak için sınırsız, üst sınırlandırılmış ve alt sınırlandırılmış joker karakterler kullanan yardımcı yöntemler yazacaksın.
Kodunu dört dosyaya düzenleyeceksin:
Food.java: Yiyecekler için basit bir sınıf hiyerarşisi oluştur. Özel birnamealanına (String), bunu başlatmak için bir kurucuya ve birgetName()yöntemine sahip bir temelFoodsınıfıyla başla. Ardından aynı dosyada iki alt sınıf oluştur:Meatextends Food (kurucusuper(name)çağrısı yapar) veVegetableextends Food (aynı düzen).Animal.java: Özel birspeciesalanına (String), bir kurucuya ve birgetSpecies()yöntemine sahip bir temelAnimalsınıfı oluştur. İki alt sınıf oluştur: Her biri Animal sınıfını genişleten ve üst sınıf kurucusunu çağıranCarnivoreveHerbivore.ZooFeeder.java: Joker karakterlerin öne çıktığı yer burası! Üç statik yönteme sahip bir yardımcı sınıf oluştur:printInventory(List<?> items)- Herhangi bir listeyi yazdırmak için sınırsız bir joker karakter kullanır. Liste üzerinde döngü oluştur ve heritem'ıtoString()kullanarak satır başına bir tane olacak şekilde yazdır.calculateTotalFood(List<? extends Food> foods)- Herhangi bir Food türündeki listeden okumak için üst sınırlandırılmış bir joker karakter kullanır. Öğe sayısınıintolarak döndür. Bu, bir üreticiden okumayı gösterir.addMeatToStock(List<? super Meat> stock, String meatName)- Meat tutabilen bir listeye yazmak için alt sınırlandırılmış bir joker karakter kullanır. Verilen adla yeni birMeatnesnesi oluştur ve bunu stoğa ekle. Bu, bir tüketiciye yazmayı gösterir.Main.java: Hayvanat bahçesi besleme sistemini bir araya getir! İki girdi alacaksın: bir et adı (String) ve bir sebze adı (String).İlk olarak bir
ArrayList<Food>oluştur ve et adıyla birMeatnesnesi ile sebze adıyla birVegetablenesnesi ekle.Food inventory:yazdır, ardından bu listeyleprintInventoryçağrısı yap.Sonra boş bir satır yazdır, ardından yiyecek listende
calculateTotalFoodkullanarakTotal food items: [count]yazdır.Son olarak
meatStockolarak adlandırılan yeni birArrayList<Food>oluştur. Boş bir satır yazdır, ardındanAdding to meat stock...yazdır. Bu liste ve"Beef"dizesiyleaddMeatToStockçağrısı yap. ArdındanMeat stock after adding:yazdır ve et stoğu üzerindeprintInventoryçağrısı yap.
İki girdiyi şu sırayla alacaksın: bir et adı ve bir sebze adı.
Yiyecek adını döndürmesi için Food sınıfında toString() yöntemini geçersiz kıl; böylece yazdırma düzgün çalışır. Her joker karakter türünün farklı bir amaca nasıl hizmet ettiğine dikkat et: yalnızca Object olarak okumaya ihtiyaç duyduğunda maksimum esneklik için ?, belirli türleri okurken ? extends ve bir koleksiyona yazarken ? super!
Kendin dene
import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String meatName = scanner.nextLine();
String vegetableName = scanner.nextLine();
// TODO: Bir ArrayList<Food> oluştur ve Meat ve Vegetable nesneleri ekle
// TODO: Print "Food inventory:" then call printInventory
// TODO: Print blank line, then "Total food items: [count]" using calculateTotalFood
// TODO: meatStock adında yeni bir ArrayList<Food> oluştur
// TODO: Print blank line, then "Adding to meat stock..."
// TODO: addMeatToStock'u meatStock ve "Beef" ile çağır
// TODO: Print "Meat stock after adding:" then call printInventory on meatStock
}
}
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ıKendi başına pratik yap: Online Java derleyicisi