Menu
Coddy logo textTech

Arayüz vs Soyut Sınıf

Coddy'nin C# Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 26 / 70.

Hem arayüzler hem de soyut sınıflar, diğer sınıfların uyması gereken sözleşmeleri tanımlamanıza olanak tanır; ancak farklı amaçlara ve belirgin yeteneklere sahiptirler.

Bir arayüz, herhangi bir uygulama içermeden bir sınıfın ne yapması gerektiğini tanımlar. Bu, saf bir sözleşmedir:

public interface IFlyable
{
    void Fly();
}

public class Bird : IFlyable
{
    public void Fly()
    {
        Console.WriteLine("Flapping wings");
    }
}

Bir soyut sınıf hem bir sözleşme hem de paylaşılan bir uygulama sağlayabilir. Kısmi bir taslaktır:

public abstract class Vehicle
{
    public string Brand { get; set; }
    
    public void StartEngine()
    {
        Console.WriteLine("Engine started");
    }
    
    public abstract void Drive();  // Uygulanmalıdır
}

public class Car : Vehicle
{
    public override void Drive()
    {
        Console.WriteLine("Driving on roads");
    }
}

Temel farklılıklar kalıtım kuralları ve amaçla ilgilidir.

Bir sınıf birden fazla arabirim uygulayabilir, ancak yalnızca bir soyut sınıftan miras alabilir.

İlişkili olmayan sınıfların davranış paylaşması gerektiğinde bir arayüz kullanın (kuşlar ve uçaklar için IFlyable gibi). İlişkili sınıflar ortak kodu ve durumu paylaştığında soyut bir sınıf kullanın (araçların motor çalıştırma mekanizmasını paylaşması gibi).

Özet sınıflar, üyelerinde kuruculara, alanlara ve erişim belirleyicilerine sahip olabilir. Arayüzler geleneksel olarak bunlara sahip olamazdı, ancak modern C# varsayılan uygulamalara izin verir.

Şüpheye düştüğünde esneklik için arayüzleri tercih et - paylaşılan uygulama gerekli hâle gelirse daha sonra her zaman soyut bir sınıf ekleyebilirsin.

challenge icon

Görev

Kolay

Arayüzlerin ve soyut sınıfların ne zaman kullanılacağını gösteren bir medya oynatıcı sistemi oluşturalım. İlişkisiz cihazların oynatma davranışını bir arayüz aracılığıyla paylaşacağı, ilişkili medya türlerinin ise ortak uygulamayı bir soyut sınıf aracılığıyla paylaşacağı bir tasarım oluşturacaksın.

Kodunu dört dosyaya ayıracaksın:

  • IPlayable.cs: IPlayable ad alanında Media adlı bir arayüz tanımla. Bu arayüz, telefon, TV veya özel bir müzik oynatıcı olması fark etmeksizin medya oynatabilen her şey için sözleşmeyi temsil eder. Play() adlı ve bir dize döndüren tek bir yöntem bildirmelidir.
  • MediaFile.cs: MediaFile ad alanında Media adlı soyut bir sınıf tanımla. Bu sınıf, tüm medya dosyalarının ortak temelini temsil eder. Bir Title özelliği (string) ve bir Duration özelliği (int, saniye cinsinden) bulunmalıdır. Her iki değeri ayarlayan bir oluşturucu ekle. GetInfo() döndüren "{Title} ({Duration}s)" adlı somut bir yöntem ekle. Ayrıca bir dize döndüren soyut GetType() yöntemini bildir; her medya türü bunun ne tür bir dosya olduğunu tanımlayacaktır.
  • AudioFile.cs: AudioFile ad alanında Media sınıfından kalıtım alan ve MediaFile arayüzünü uygulayan bir IPlayable sınıfı tanımla. Bir Artist özelliği (string) ekle. Oluşturucu başlık, süre ve sanatçı değerlerini kabul etmelidir. GetType() yöntemini "Audio" döndürecek şekilde geçersiz kıl. Play() yöntemini "Playing audio: {Title} by {Artist}" döndürecek şekilde uygula.
  • Program.cs: Ana dosyanda, girdi değerlerini kullanarak bir AudioFile oluştur. Sınıfın her iki yönünü de göster: GetInfo() ve GetType() yöntemlerini (soyut sınıftan miras alınan) çağır, ardından Play() yöntemini (arayüzden) çağır. Ses dosyasını bir IPlayable değişkeninde sakla ve arayüz çok biçimliliğini göstermek için Play() yöntemini tekrar çağır.

Üç girdi alacaksın:

  • Şarkı adı
  • Saniye cinsinden süre
  • Sanatçı adı

Çıktıyı şu biçimde yazdır:

Info: {GetInfo() result}
Type: {GetType() result}
Direct: {Play() result}
Via Interface: {Play() result from IPlayable variable}

Örneğin girdiler Bohemian Rhapsody, 354 ve Queen ise çıktı şu şekilde olmalıdır:

Info: Bohemian Rhapsody (354s)
Type: Audio
Direct: Playing audio: Bohemian Rhapsody by Queen
Via Interface: Playing audio: Bohemian Rhapsody by Queen

AudioFile sınıfının her iki yaklaşımdan da nasıl yararlandığına dikkat et: soyut sınıftan ortak uygulamayı (GetInfo()) miras alırken aynı zamanda IPlayable sözleşmesini de yerine getirir. Soyut sınıf, ilişkili medya türleri için kodun yeniden kullanılmasını sağlarken arayüz, herhangi bir ilgisiz sınıfın aynı kalıtım hiyerarşisini paylaşmadan "oynatılabilir" olmasına olanak tanır.

Kendin dene

using System;
using Media;

class Program
{
    public static void Main(string[] args)
    {
        // Giriş değerlerini oku
        string title = Console.ReadLine();
        int duration = Convert.ToInt32(Console.ReadLine());
        string artist = Console.ReadLine();
        
        // TODO: Giriş değerlerini kullanarak bir AudioFile oluştur
        
        // TODO: Info: yazdır, ardından GetInfo() sonucunu
        
        // TODO: Type: yazdır, ardından GetType() sonucunu
        
        // TODO: Direct: yazdır, ardından Play() sonucunu
        
        // TODO: Ses dosyasını bir IPlayable değişkeninde sakla
        
        // TODO: Via Interface: yazdır, ardından IPlayable değişkeninden Play() sonucunu
    }
}
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 C# derleyicisi