Menu
Coddy logo textTech

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:

ÖzellikAbstract ClassInterface
Örnek değişkenleriEvetYalnızca sabitler
YapıcılarEvetHayır
Çoklu kalıtımHayır (tek extends)Evet (birden çok implements)
Erişim belirleyicileriHerhangi biriYalnı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.

challenge icon

Görev

Kolay

Bir 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 bir brand alanı (String) ve bir year alanı (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 bir startEngine() metodu ekle. Ayrıca [brand] ([year]) döndüren somut bir getInfo() 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() ve closeRoof().
  • Car.java: Vehicle sınıfını genişleten ve Convertible arayüzünü uygulayan bir sınıf oluştur. Bir Car, ek olarak numDoors alanına (int) sahiptir. Miras alınan alanları başlatmak için super kullan. startEngine() metodunu [brand] car engine started döndürecek şekilde uygula. openRoof() metodunu [brand] roof opening, closeRoof() metodunu ise [brand] roof closing döndürecek şekilde uygula.
  • Motorcycle.java: Vehicle sınıfını genişleten ancak Convertible arayüzünü uygulamayan bir sınıf oluştur: motosikletlerin tavanı yoktur! Bir Motorcycle, hasSidecar alanına (boolean) sahiptir. startEngine() metodunu [brand] motorcycle engine roaring dö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çin startEngine() 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, Convertible arayüzünü uyguladığı için otomobil üzerinde openRoof() metodunu çağırıp yazdır, ardından closeRoof() 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)
    }
}
quiz iconKendini test et

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

Kendi başına pratik yap: Online Java derleyicisi