Menu
Coddy logo textTech

Soyut Sınıflar

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

Öz sınıf, en az bir saf sanal işlev içeren herhangi bir sınıftır. Eksik bir arayüze sahip olduğu için bir öz sınıfın nesnelerini doğrudan oluşturamazsınız - bu sınıf yalnızca miras alınmak amacıyla vardır.

class Shape {
public:
    virtual double area() = 0;      // Saf sanal - Shape'i soyut yapar
    virtual double perimeter() = 0; // Başka bir saf sanal fonksiyon
    
    void printInfo() {              // Normal metot - implementasyonu var
        std::cout << "Area: " << area() << std::endl;
    }
    
    virtual ~Shape() = default;
};

Shape s;  // Hata: soyut sınıf örneği oluşturulamaz

Soyut sınıflar, saf sanal işlevlerin (uygulaması olmayan), normal sanal işlevlerin (varsayılan uygulamaya sahip) ve sanal olmayan işlevlerin bir karışımını içerebilir. Bu, ortak davranışı tanımlamanıza olanak tanırken türetilmiş sınıfların belirli işlevleri uygulamasını gerektirir.

class Circle : public Shape {
    double radius;
public:
    Circle(double r) : radius(r) {}
    
    double area() override { return 3.14159 * radius * radius; }
    double perimeter() override { return 2 * 3.14159 * radius; }
};

Circle c(5.0);      // OK: Circle tüm pure virtual fonksiyonları uygular
c.printInfo();      // Kalıtılan printInfo()'yu kullanır, Circle'ın area()'sını çağırır

Türetilmiş bir sınıfın somut (örneği oluşturulabilir) hâle gelmesi için tüm saf sanal işlevleri uygulaması gerekir. Herhangi birini uygulamadan bırakırsa kendisi de soyut kalır. Bu mekanizma, hiyerarşinizdeki her somut sınıfın gerekli işlevselliği sağlamasını güvence altına alır.

challenge icon

Görev

Kolay

Farklı medya türleri için soyut sınıfların sözleşmeleri nasıl tanımladığını gösteren bir medya oynatıcı sistemi oluşturalım. Her medya oynatıcının ne yapması gerektiğini belirleyen soyut bir temel sınıf oluşturacak, ardından ses ve video içerikleri için somut oynatıcılar uygulayacaksın.

Kodunu üç dosyaya ayıracaksın:

  • MediaPlayer.h: Tüm medya türleri için şablon görevi gören soyut bir MediaPlayer sınıfı tanımla. Soyut sınıfında şunlar bulunmalı:
    • Korumalı bir std::string title üyesi
    • Korumalı bir int duration üyesi (saniye cinsinden)
    • Her iki değeri başlatan bir kurucu
    • Salt sanal bir play() yöntemi: her medya türü farklı şekilde oynatılacak
    • Bir getMediaType() döndüren salt sanal bir std::string yöntemi
    • Şunu yazdıran normal (sanal olmayan) bir showInfo() yöntemi: <title> (<duration>s) - Type: <mediaType>. Bu yöntem, türü almak için getMediaType() yöntemini çağırmalı
    • Sanal bir yok edici
  • Players.h: MediaPlayer sınıfından kalıtım alan iki somut medya oynatıcı uygula:

    AudioPlayer:

    • Özel bir std::string artist üyesi
    • Başlık, süre ve sanatçı alan bir kurucu
    • play() yöntemini şu çıktıyı verecek şekilde uygula: Playing audio: <title> by <artist>
    • getMediaType() yöntemini "Audio" döndürecek şekilde uygula

    VideoPlayer:

    • Özel bir std::string resolution üyesi
    • Başlık, süre ve çözünürlük alan bir kurucu
    • play() yöntemini şu çıktıyı verecek şekilde uygula: Playing video: <title> in <resolution>
    • getMediaType() yöntemini "Video" döndürecek şekilde uygula
  • main.cpp: Dört girdi oku (her biri ayrı bir satırda):
    1. Ses parçası başlığı
    2. Ses süresi (tam sayı)
    3. Video başlığı
    4. Video süresi (tam sayı)

    Sanatçısı AudioPlayer olan bir "Unknown Artist" ve çözünürlüğü VideoPlayer olan bir "1080p" oluştur. Her ikisini de MediaPlayer* işaretçilerinden oluşan bir dizide sakla.

    Dizi üzerinde döngü kurarak her oynatıcı için önce showInfo(), ardından play() çağrısını yap. Her medya öğesi arasında boş bir satır yazdır. İşin bittiğinde dinamik olarak ayrılmış nesnelerin belleğini temizle.

Örneğin girdiler Summer Vibes, 180, Nature Documentary ve 3600 olduğunda:

Summer Vibes (180s) - Type: Audio
Playing audio: Summer Vibes by Unknown Artist

Nature Documentary (3600s) - Type: Video
Playing video: Nature Documentary in 1080p

showInfo() yönteminin soyut temel sınıfta yalnızca bir kez tanımlandığı, ancak salt sanal getMediaType() yöntemini çağırdığına dikkat et. Bu, soyut sınıfların somut uygulamaları, türetilmiş sınıfların sağlaması gereken yöntemlerle bir arada kullanabileceğini gösterir. Geçersiz kılınan tüm yöntemlerde override anahtar sözcüğünü kullanmayı unutma.

Kendin dene

#include <iostream>
#include <string>
#include "MediaPlayer.h"
#include "Players.h"

int main() {
    // Girdileri oku
    std::string audioTitle;
    int audioDuration;
    std::string videoTitle;
    int videoDuration;
    
    std::getline(std::cin, audioTitle);
    std::cin >> audioDuration;
    std::cin.ignore();
    std::getline(std::cin, videoTitle);
    std::cin >> videoDuration;
    
    // TODO: "Unknown Artist" sanatçısıyla bir AudioPlayer oluştur
    
    // TODO: "1080p" çözünürlüğüne sahip bir VideoPlayer oluştur
    
    // TODO: Her ikisini de MediaPlayer* işaretçilerinden oluşan bir dizide sakla
    
    // TODO: Diziyi döngüyle gez ve her oynatıcı için:
    //       1. showInfo() çağır
    //       2. play() çağır
    //       3. Her medya öğesi arasında boş bir satır yazdır
    
    // TODO: Dinamik olarak ayrılmış nesneleri temizle
    
    return 0;
}
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