Wildcard'lar (?, extends, super)
Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 57 / 87.
Sınırlı tür parametreleri, jenerikleri belirli türlerle kısıtlar; ancak mevcut jenerik türlerle çalışırken tam tür parametresini bilmiyorsanız veya önemsemiyorsanız ne olacak? İşte joker karakterler burada 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 kılavuz: yalnızca okuma yaptığınızda (üretici) extends kullanın, yalnızca yazma yaptığınızda (tüketici) super kullanın. Bu, PECS ilkesi olarak bilinir: Üretici Extends, Tüketici 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ı metotlar yazacaksın.
Kodunu dört dosyaya ayıracaksın:
Food.java: Yiyecekler için basit bir sınıf hiyerarşisi oluştur:Foodadlı,name(String) adında private bir alanı, bunu başlatan bir kurucusu ve birgetName()metodu olan temel sınıfla başla. Ardından aynı dosyada iki alt sınıf oluştur:Meat, Food sınıfını genişletsin (kurucususuper(name)çağrısını yapsın) veVegetable, Food sınıfını genişletsin (aynı düzeni kullansın).Animal.java:Animal(String) adında private bir alanı, bir kurucusu ve birspeciesmetodu olan temelgetSpecies()sınıfını oluştur. İki alt sınıf oluştur:CarnivoreveHerbivore; her biri Animal sınıfını genişletsin ve üst sınıfın kurucusunu çağırsın.ZooFeeder.java: Joker karakterlerin öne çıktığı yer burası! Üç static metodu olan 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ü kur ve her öğeyitoString()kullanarak satır başına bir öğe 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ı birintolarak döndür. Bu, bir üreticiden okuma işlemini 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 yazma işlemini 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).Önce bir
ArrayList<Food>oluştur ve et adıyla birMeatnesnesi ile sebze adıyla birVegetablenesnesi ekle.Food inventory:yazdır, ardından bu listeyleprintInventorymetodunu çağır.Sonra boş bir satır yazdır, ardından yiyecek listen üzerinde
Total food items: [count]kullanarakcalculateTotalFoodyazdır.Son olarak
ArrayList<Food>adında yeni birmeatStockoluştur. Boş bir satır yazdır, ardındanAdding to meat stock...yazdır. Bu listeyi veaddMeatToStockdizesini kullanarak"Beef"metodunu çağır. ArdındanMeat stock after adding:yazdır ve et stoğu üzerindeprintInventorymetodunu çağır.
Sırasıyla iki girdi alacaksın: bir et adı ve bir sebze adı.
Yazdırmanın doğru çalışması için Food sınıfında toString() metodunu, yiyeceğin adını döndürecek şekilde geçersiz kıl. Her joker karakter türünün farklı bir amaca hizmet ettiğine dikkat et: yalnızca Object olarak okuma yapman gerektiğinde 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