Neden Çoklu Sınıf Kalıtımı Yok?
Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 26 / 87.
Java, bir sınıfın birden fazla sınıfı genişletmesini kasten engeller. Bu kısıtlama, Diamond Problem olarak bilinen bir sorun nedeniyle mevcuttur.
Java'nın çoklu kalıtıma izin verdiğini hayal edin. Şu varsayımsal senaryoyu düşünün:
// Bu kod Java'da geçerli DEĞİLDİR
public class A {
public void greet() {
System.out.println("Hello from A");
}
}
public class B extends A {
@Override
public void greet() {
System.out.println("Hello from B");
}
}
public class C extends A {
@Override
public void greet() {
System.out.println("Hello from C");
}
}
// Java'da izin verilmez!
public class D extends B, C { }Bir D nesnesi üzerinde greet() metodunu çağırdıysanız, hangi sürüm çalışmalı? B'den gelen mi yoksa C'den gelen mi? Bu belirsizlik, kalıtım diyagramının oluşturduğu elmas şeklinden adını alan Elmas Problemi'dir (Diamond Problem).
Java'nın çözümü basittir: sınıfların yalnızca tekli kalıtımına izin verir. Ancak, Java bir alternatif sunar. Bir sınıf, gelecek bir bölümde öğreneceğiniz birden fazla arayüzü uygulayabilir.
Arayüzler elmas problemini farklı şekilde çözer ve size belirsizlik olmadan esneklik sağlar.
// Bu Java'da geçerlidir
public class Dog extends Animal implements Runnable, Comparable<Dog> {
// Birden fazla arayüz uygulanabilir
}Bu tasarım tercihi, Java'nın kalıtım modelini temiz ve öngörülebilir tutarken, arayüzler aracılığıyla güçlü kod yeniden kullanımına olanak tanır.
Görev
KolayJava'nın tekli kalıtım kuralını gösteren ve bu kısıt içinde nasıl esnek tasarımlar oluşturabileceğinizi ortaya koyan bir müzik çalar sistemi oluşturalım.
Bir müzik çaların ve sesli asistanın özelliklerini birleştiren akıllı bir hoparlör oluşturmak istediğinizi düşünün. Java birden fazla sınıfı extends etmeye izin vermediğinden, tekli kalıtımı kullanarak hiyerarşinizi dikkatlice tasarlamanız gerekir.
Kodunuzu düzenlemek için dört dosya oluşturacaksınız:
AudioDevice.java: Tüm ses çalan cihazların ortak kullanacağı temel sınıfı oluşturun. Şunlara sahip olmalıdır:deviceName(String) için private bir alan- Cihaz adını kabul eden bir constructor
- Adı döndüren bir
getDeviceName()metodu - Şunu yazdıran bir
playSound()metodu:[deviceName]: Playing audio
MusicPlayer.java: AudioDevice sınıfını extends eden ve müziğe özgü özellikler ekleyen bir sınıf oluşturun:currentSong(String) için private bir alan- Cihaz adını alan ve
super(deviceName)kullanan bir constructor - Mevcut şarkıyı ayarlayan bir
setSong(String song)metodu - Şunu yazdıracak şekilde
playSound()metodunu override edin:[deviceName]: Now playing - [currentSong]
SmartSpeaker.java: MusicPlayer sınıfını extends eden bir sınıf oluşturun (hem MusicPlayer hem de bir VoiceAssistant sınıfını extends etmeyin; bu multiple inheritance olur!). Akıllı hoparlör, ses özellikleri ekleyerek müzik çaların üzerine inşa edilir:assistantName(String) için private bir alan- Cihaz adını ve asistan adını alan,
super(deviceName)kullanan bir constructor - Şunu yazdıran bir
voiceCommand(String command)metodu:[assistantName]: Processing "[command]" - Şunu yazdıran bir
getFullInfo()metodu:[deviceName] with [assistantName] assistant
Main.java: Çok seviyeli kalıtım zincirinizi gösterin. Üç girdi alacaksınız: bir cihaz adı (String), bir asistan adı (String) ve bir şarkı adı (String). Bir SmartSpeaker oluşturun, bir şarkı ayarlayın ve ardından şu metotları sırayla çağırın:getFullInfo()playSound()voiceCommand("skip to next")
Üç girdi alacaksınız: cihaz adı, asistan adı ve şarkı adı.
SmartSpeaker'ın birden fazla ilgisiz sınıfı extends etmeye çalışmak yerine, bir zincir içinde (AudioDevice -> MusicPlayer -> SmartSpeaker) MusicPlayer'ı extends ederek müzik özellikleri kazandığına dikkat edin. Java'nın kalıtımı düzenli ve belirsizlikten uzak tutma yaklaşımı budur!
Kendin dene
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Girdileri oku
String deviceName = scanner.nextLine();
String assistantName = scanner.nextLine();
String songName = scanner.nextLine();
// TODO: deviceName ve assistantName ile bir SmartSpeaker oluşturun
// TODO: setSong() kullanarak şarkıyı ayarlayın
// TODO: getFullInfo() metodunu çağırın
// TODO: playSound() metodunu çağırın
// TODO: voiceCommand("skip to next") 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ıKendi başına pratik yap: Online Java derleyicisi