Sealed Classes (Java 17+)
Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 52 / 87.
Geleneksel Java'da, bir sınıf oluşturduğunuzda, başka herhangi bir sınıf onu genişletebilir (onu final olarak işaretlemediğiniz sürece). Peki ya kalıtıma izin vermek istiyor ama bunun herhangi biri tarafından yapılmasını istemiyorsanız? Java 17, hangi sınıfların sizinkini genişletebileceği üzerinde size hassas kontrol sağlamak için sealed classes (mühürlü sınıflar) özelliğini getirdi.
Bir sealed class (mühürlü sınıf), sealed ve permits anahtar kelimelerini kullanarak izin verilen alt sınıflarını açıkça bildirir:
sealed class Shape permits Circle, Rectangle, Triangle {
abstract double area();
}
final class Circle extends Shape {
double radius;
double area() { return Math.PI * radius * radius; }
}
final class Rectangle extends Shape {
double width, height;
double area() { return width * height; }
}
final class Triangle extends Shape {
double base, height;
double area() { return 0.5 * base * height; }
}Sadece Circle, Rectangle ve Triangle sınıfları Shape sınıfını genişletebilir. Onu genişletmeye çalışan diğer tüm sınıflar bir derleme hatasına neden olacaktır.
İzin verilen her alt sınıf üç değiştiriciden birini kullanmalıdır: final (daha fazla genişletme yapılamaz), sealed (kısıtlama zincirini devam ettirir) veya non-sealed (kısıtlamasız genişletmeye açar):
sealed class Vehicle permits Car, Truck { }
final class Car extends Vehicle { } // Genişletilemez
non-sealed class Truck extends Vehicle { } // Herkes Truck sınıfını genişletebilirSealed sınıflar, derleyici tüm olası alt türleri bildiği ve kapsamlılığı doğrulayabildiği için switch ifadelerindeki desen eşleştirme (pattern matching) ile özellikle güçlüdür. Ödeme yöntemleri, yanıt türleri veya geometrik şekiller gibi bir etki alanındaki sabit bir tür kümesini modellerken idealdirler.
Görev
KolayUygulamanızda hangi tür bildirimlerin var olabileceğini kısıtlayarak mühürlü (sealed) sınıfları gösteren bir bildirim sistemi kuralım. Sadece belirli bildirim türlerine izin verilen bir hiyerarşi oluşturacaksınız ve her tür, teslimatı farklı şekilde gerçekleştirecek.
Kodunuzu dört dosya halinde düzenleyeceksiniz:
Notification.java: Tüm bildirimler için temel görevi gören mühürlü (sealed) bir soyut sınıf oluşturun. Tam olarak üç alt sınıfa izin vermelidir:EmailNotification,SMSNotificationvePushNotification. Mühürlü sınıfınızın korumalı (protected) birmessage(String) alanına, bunu başlatan bir yapıcıya (constructor), mesaj için bir getter metoduna ve bildirimin nasıl gönderildiğini açıklayan bir String döndüren soyut birdeliver()metoduna ihtiyacı vardır.EmailNotification.java: Notification sınıfını genişletenfinalbir sınıf oluşturun. Bir EmailNotification, e-posta adresi için ek bir özel (private)recipient(String) alanına sahiptir. Yapıcısı hem mesajı hem de alıcıyı almalı vesuper()ile üst sınıf yapıcısını çağırmalıdır.deliver()metodu şu değeri döndürmelidir:"Sending email to " + recipient + ": " + messageSMSNotification.java: Notification sınıfını genişletennon-sealedbir sınıf oluşturun; bu, gelecekte gerekirse diğer sınıfların onu genişletmesine olanak tanır. Bir SMSNotification, ek bir özel (private)phoneNumber(String) alanına sahiptir. Yapıcısı mesajı ve telefon numarasını alır.deliver()metodu şu değeri döndürmelidir:"Sending SMS to " + phoneNumber + ": " + messagePushNotification.java: Notification sınıfını genişletenfinalbir sınıf oluşturun. Bir PushNotification, ek bir özel (private)deviceId(String) alanına sahiptir. Yapıcısı mesajı ve cihaz kimliğini alır.deliver()metodu şu değeri döndürmelidir:"Sending push to device " + deviceId + ": " + messageMain.java: Bildirim sisteminizi bir araya getirin! Dört girdi alacaksınız: bir mesaj (String), bir e-posta adresi (String), bir telefon numarası (String) ve bir cihaz kimliği (String).Aynı mesajı ancak ilgili iletişim bilgilerini kullanarak her bildirim türünden birer tane oluşturun. Mühürlü sınıflarla polimorfizmi (çok biçimlilik) göstermek için üçünü de
Notification[]tipinde bir dizide saklayın. Ardından dizi boyunca ilerleyin ve her bildirimdedeliver()metodunu çağırmanın sonucunu yazdırın.
Sırasıyla dört girdi alacaksınız: mesaj, e-posta adresi, telefon numarası ve cihaz kimliği.
Mühürlü sınıfın hiyerarşiyi nasıl kısıtladığına dikkat edin; yalnızca izin verilen üç sınıf Notification sınıfını genişletebilir. Her alt sınıf kendisini final, sealed veya non-sealed olarak bildirmelidir. Bu, polimorfizmi etkin kılarken tip hiyerarşiniz üzerinde tam kontrol sahibi olmanızı sağlar!
Kopya kağıdı
Bir sealed class (mühürlü sınıf), sealed ve permits anahtar kelimelerini kullanarak hangi sınıfların onu genişletebileceğini kısıtlar:
sealed class Shape permits Circle, Rectangle, Triangle {
abstract double area();
}Yalnızca permits kısmında listelenen sınıflar mühürlü sınıfı genişletebilir. Onu genişletmeye çalışan diğer tüm sınıflar derleme hatasına neden olur.
İzin verilen her alt sınıf üç değiştiriciden birini kullanmalıdır:
final- daha fazla genişletmeyi engellersealed- kısıtlama zincirini kendi izin verilen alt sınıflarıyla devam ettirirnon-sealed- hiyerarşiyi kısıtlamasız genişletmeye açar
sealed class Vehicle permits Car, Truck { }
final class Car extends Vehicle { } // Genişletilemez
non-sealed class Truck extends Vehicle { } // Herkes Truck sınıfını genişletebilirMühürlü sınıflar, ödeme yöntemleri, yanıt türleri veya geometrik şekiller gibi bir alandaki sabit bir tür kümesini modellemek için kullanışlıdır. Derleyici tüm olası alt türleri bildiği için switch ifadelerindeki desen eşleştirme (pattern matching) ile iyi çalışırlar.
Kendin dene
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Dört girişi oku
String message = scanner.nextLine();
String email = scanner.nextLine();
String phoneNumber = scanner.nextLine();
String deviceId = scanner.nextLine();
// TODO: Aynı mesajı kullanarak her bildirim türünden birer tane oluşturun
// - message ve email ile EmailNotification
// - message ve phoneNumber ile SMSNotification
// - message ve deviceId ile PushNotification
// TODO: Üç bildirimin tümünü bir Notification[] dizisinde saklayın
// Bu, sealed sınıflar ile polimorfizmi gösterir
// TODO: Dizi üzerinde döngü kurun ve deliver() sonucunu yazdırın
// her bildirim için
}
}
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ı