Soyut Sınıflar ve Arayüzler
Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 38 / 87.
Artık hem soyut sınıfları hem de arayüzleri anladığınıza göre yaygın bir soru ortaya çıkar: Birini diğerine tercih ederek ne zaman kullanmalısınız? Seçim, neyi modellemeye çalıştığınıza bağlıdır.
Sınıflar ortak durum veya davranışa sahip ortak bir temel paylaştığında soyut sınıf kullanın. Soyut sınıflarda örnek değişkenleri, kurucular ve soyut ve somut yöntemlerin bir karışımı bulunabilir:
public abstract class Animal {
protected String name; // paylaşılan durum
public Animal(String name) {
this.name = name;
}
public void sleep() { // paylaşılan davranış
System.out.println(name + " is sleeping");
}
public abstract void makeSound(); // uygulanmalıdır
}Birbiriyle ilişkili olmayan sınıfların paylaşabileceği bir yetenek tanımlamak istediğinde arayüz kullan. Arayüzler, bir nesnenin ne olduğuna değil, ne yapabileceğine odaklanır:
public interface Flyable {
void fly();
}
// İlgisiz sınıflar bu yeteneği paylaşabilir
class Bird extends Animal implements Flyable { ... }
class Airplane implements Flyable { ... }
class Drone implements Flyable { ... }İşte hızlı bir karşılaştırma:
| Özellik | Abstract Class | Interface |
|---|---|---|
| Örnek değişkenleri | Evet | Yalnızca sabitler |
| Yapıcılar | Evet | Hayır |
| Çoklu kalıtım | Hayır (tek extends) | Evet (birden çok implements) |
| Erişim belirleyicileri | Herhangi biri | Yalnızca public (abstract metotlar için) |
Pratik bir kılavuz: Kendinizi yalnızca soyut yöntemler içeren ve durumu olmayan bir soyut sınıf oluştururken buluyorsanız, büyük olasılıkla arayüz daha iyi bir seçimdir.
Görev
KolayBir araç sistemini, soyut sınıfların ve arayüzlerin ne zaman kullanılacağını gösterecek şekilde oluşturalım. Ortak durum ve davranışları bir soyut sınıf aracılığıyla paylaşan araçları modelleyecek, isteğe bağlı yetenekleri ise arayüzler aracılığıyla ekleyeceksin.
Kodunu beş dosyaya ayıracaksın:
Vehicle.java: Tüm araçların temelini oluşturan bir soyut sınıf oluştur. Her aracın birbrandalanı (String) ve biryearalanı (int) vardır. Her iki alanı başlatmak için bir yapıcı, her biri için getter metotları ve String döndüren soyut birstartEngine()metodu ekle. Ayrıca[brand] ([year])döndüren somut birgetInfo()metodu da ekle. Bu, soyut sınıf için mükemmel bir kullanım durumudur: araçlar durumu (brand, year) ve bazı davranışları (getInfo) paylaşır, ancak her biri motorunu farklı şekilde çalıştırır.Convertible.java: Tavanını açıp kapatabilen araçlar için bir arayüz tanımla. Bu yetenek, bir aracın ne olduğuyla ilgili değildir: belirli araçların yapabildiği bir şeydir. İkisi de String döndüren iki metot tanımla:openRoof()vecloseRoof().Car.java:Vehiclesınıfını genişleten veConvertiblearayüzünü uygulayan bir sınıf oluştur. Bir Car, ek olaraknumDoorsalanına (int) sahiptir. Miras alınan alanları başlatmak içinsuperkullan.startEngine()metodunu[brand] car engine starteddöndürecek şekilde uygula.openRoof()metodunu[brand] roof opening,closeRoof()metodunu ise[brand] roof closingdöndürecek şekilde uygula.Motorcycle.java:Vehiclesınıfını genişleten ancakConvertiblearayüzünü uygulamayan bir sınıf oluştur: motosikletlerin tavanı yoktur! Bir Motorcycle,hasSidecaralanına (boolean) sahiptir.startEngine()metodunu[brand] motorcycle engine roaringdöndürecek şekilde uygula.Main.java: Soyut sınıflar ile arayüzler arasındaki farkı göstermek için her şeyi bir araya getir. Dört girdi alacaksın: bir otomobil markası, bir otomobil yılı, bir motosiklet markası ve bir motosiklet yılı.Bir Car (4 kapılı) ve bir Motorcycle (yan sepet olmadan) oluştur. İlk olarak, her iki araç için
getInfo()metodunu yazdırarak paylaşılan soyut sınıf davranışını göster. Bu metodu her ikisi de Vehicle sınıfından miras alır. Ardından her biri içinstartEngine()sonucunu yazdır: her araç türünün bunu nasıl farklı şekilde uyguladığına dikkat et.Son olarak arayüz yeteneğini göster: yalnızca Car,
Convertiblearayüzünü uyguladığı için otomobil üzerindeopenRoof()metodunu çağırıp yazdır, ardındancloseRoof()metodunu çağırıp yazdır.
Dört girdi alacaksın: otomobil markası (String), otomobil yılı (int), motosiklet markası (String) ve motosiklet yılı (int).
Çıktın toplam altı satır göstermelidir. Her iki aracın da soyut sınıfın durumunu ve getInfo() metodunu paylaştığına, ancak yalnızca Car'ın açılır tavan yeteneğine sahip olduğuna dikkat et. Bu, her yaklaşımın ne zaman kullanılacağını gösterir!
Kendin dene
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Girdileri oku
String carBrand = scanner.nextLine();
int carYear = scanner.nextInt();
scanner.nextLine(); // yeni satırı tüket
String motorcycleBrand = scanner.nextLine();
int motorcycleYear = scanner.nextInt();
// TODO: 4 kapılı bir Car oluştur
// TODO: sidecar olmadan bir Motorcycle oluştur (false)
// TODO: Her iki araç için getInfo() yazdır (paylaşılan soyut sınıf davranışını gösterir)
// TODO: Her iki araç için startEngine() yazdır (farklı implementasyonları gösterir)
// TODO: Yalnızca araba için openRoof() ve closeRoof() yazdır (arayüz yeteneğini gösterir)
}
}
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