Soyut Sınıflar
Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 60 / 104.
Bir soyut sınıf (abstract class), en az bir saf sanal fonksiyon (pure virtual function) içeren herhangi bir sınıftır. Eksik bir arayüze sahip olduğu için, bir soyut sınıftan doğrudan nesne oluşturamazsınız; bu sınıf yalnızca kendisinden miras alınması için mevcuttur.
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 - uygulaması var
std::cout << "Area: " << area() << std::endl;
}
virtual ~Shape() = default;
};
Shape s; // Hata: soyut sınıftan nesne oluşturulamazSoyut sınıflar; saf sanal fonksiyonların (uygulaması olmayan), normal sanal fonksiyonların (varsayılan uygulaması olan) ve sanal olmayan fonksiyonların bir karışımını içerebilir. Bu, türetilmiş sınıfların belirli işlevleri uygulamasını zorunlu kılarken, ortak davranışları tanımlamanıza olanak tanır.
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); // Tamam: Circle tüm saf sanal fonksiyonları uygular
c.printInfo(); // Kalıtım alınan printInfo() fonksiyonunu kullanır, Circle'ın area() fonksiyonunu çağırırTüretilmiş bir sınıf, somut (örneklenebilir) hale gelmek için tüm saf sanal fonksiyonları uygulamalıdır. Eğer herhangi birini uygulanmamış bırakırsa, kendisi de soyut kalmaya devam eder. Bu mekanizma, hiyerarşinizdeki her somut sınıfın gerekli işlevselliği sağlamasını garanti eder.
Görev
KolayFarklı medya türleri için soyut sınıfların nasıl sözleşmeler 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çeriği için somut oynatıcılar uygulayacaksınız.
Kodunuzu üç dosya halinde düzenleyeceksiniz:
MediaPlayer.h: Tüm medya türleri için bir taslak görevi gören soyut birMediaPlayersınıfı tanımlayın. Soyut sınıfınız şunlara sahip olmalıdır:- Korumalı (protected) bir
std::string titleüyesi - Korumalı (protected) bir
int durationüyesi (saniye cinsinden) - Her iki değeri de başlatan bir yapıcı (constructor)
- Saf sanal (pure virtual) bir
play()metodu — her medya türü farklı şekilde oynatılacaktır std::stringdöndüren saf sanal (pure virtual) birgetMediaType()metodu- Şunu yazdıran normal (sanal olmayan) bir
showInfo()metodu:<title> (<duration>s) - Type: <mediaType>— bu metod, türü almak içingetMediaType()metodunu çağırmalıdır - Sanal bir yıkıcı (virtual destructor)
- Korumalı (protected) bir
Players.h:MediaPlayersınıfından miras alan iki somut medya oynatıcı uygulayın:AudioPlayer:- Özel (private) bir
std::string artistüyesi - Başlık, süre ve sanatçı alan bir yapıcı
- Şunu yazdırmak için
play()metodunu uygulayın:Playing audio: <title> by <artist> "Audio"döndürmek içingetMediaType()metodunu uygulayın
VideoPlayer:- Özel (private) bir
std::string resolutionüyesi - Başlık, süre ve çözünürlük alan bir yapıcı
- Şunu yazdırmak için
play()metodunu uygulayın:Playing video: <title> in <resolution> "Video"döndürmek içingetMediaType()metodunu uygulayın
- Özel (private) bir
main.cpp: Dört girdi okuyun (her biri ayrı bir satırda):- Ses parçası başlığı
- Ses süresi (tam sayı)
- Video başlığı
- Video süresi (tam sayı)
Sanatçısı
"Unknown Artist"olan birAudioPlayerve çözünürlüğü"1080p"olan birVideoPlayeroluşturun. Her ikisini de birMediaPlayer*işaretçi dizisinde saklayın.Dizi boyunca döngü kurun ve her oynatıcı için önce
showInfo(), ardındanplay()metodunu çağırın. Her medya öğesi arasına boş bir satır yazdırın. İşiniz bittiğinde dinamik olarak ayrılmış nesnelerinizi temizleyin.
Örneğin, Summer Vibes, 180, Nature Documentary ve 3600 girdileriyle:
Summer Vibes (180s) - Type: Audio
Playing audio: Summer Vibes by Unknown Artist
Nature Documentary (3600s) - Type: Video
Playing video: Nature Documentary in 1080pshowInfo() metodunun soyut temel sınıfta bir kez nasıl tanımlandığına ancak saf sanal getMediaType() metodunu nasıl çağırdığına dikkat edin — bu, soyut sınıfların somut uygulamaları, türetilmiş sınıfların sağlaması gereken metodlarla nasıl harmanlayabileceğini gösterir. Geçersiz kılınan (overridden) tüm metodlarda override anahtar kelimesini kullanmayı unutmayın.
Kopya kağıdı
Bir soyut sınıf (abstract class), en az bir saf sanal (pure virtual) fonksiyon içerir ve doğrudan örneklendirilemez. Kendisinden miras alınması ve türetilmiş sınıflar için bir arayüz tanımlaması amacıyla vardır.
Bir Soyut Sınıf Tanımlama
Saf sanal bir fonksiyon bildirmek için = 0 kullanın:
class Shape {
public:
virtual double area() = 0; // Saf sanal fonksiyon
virtual double perimeter() = 0; // Shape'i soyut yapar
void printInfo() { // Uygulaması olan normal metot
std::cout << "Area: " << area() << std::endl;
}
virtual ~Shape() = default; // Sanal yıkıcı
};Soyut sınıflar şunları içerebilir:
- Saf sanal fonksiyonlar (uygulama içermez)
- Normal sanal fonksiyonlar (varsayılan uygulama ile)
- Sanal olmayan fonksiyonlar
Somut Sınıfları Uygulama
Türetilmiş bir sınıfın örneklendirilebilir hale gelmesi için tüm saf sanal fonksiyonları uygulaması gerekir:
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); // Tamam: tüm saf sanal fonksiyonlar uygulandı
c.printInfo(); // Miras alınan metot Circle'ın area() fonksiyonunu çağırırEğer türetilmiş bir sınıf tüm saf sanal fonksiyonları uygulamazsa, soyut kalmaya devam eder ve örneklendirilemez.
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: Sanatçısı "Unknown Artist" olan bir AudioPlayer oluşturun
// TODO: Çözünürlüğü "1080p" olan bir VideoPlayer oluşturun
// TODO: Her ikisini de bir MediaPlayer* işaretçi dizisinde saklayın
// TODO: Dizi boyunca döngü kurun ve her oynatıcı için:
// 1. showInfo() fonksiyonunu çağırın
// 2. play() fonksiyonunu çağırın
// 3. Her medya öğesi arasına boş bir satır yazdırın
// TODO: Dinamik olarak ayrılmış nesneleri temizleyin
return 0;
}
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 DosyalarC++ Build ve DerlemeBaşlık Dosyaları ve Kaynak DosyalarıAd Alanları ve KapsamC++'ta OOP'ye GirişSınıflar ve Nesneler'this' İşaretçisiMetotlar (Üye Fonksiyonlar)Öznitelikler (Veri Üyeleri)Ctor ve Dtor TemelleriÖzet - Basit Hesap Makinesi4Sınıf Özellikleri
Örnek ve Statik ÜyelerGetter ve Setter MetotlarıConst Üye FonksiyonlarMutable Anahtar KelimesiStatik Metotlar ve DeğişkenlerFriend Fonksiyonlar ve SınıflarÖzet - Banka Hesabı Yöneticisi7Kalıtım
Temel KalıtımKalıtım Erişim SeviyeleriCtor ve Dtor Çağrılma SırasıMetot Geçersiz KılmaSanal Fonksiyonlar ve VTableÇoklu KalıtımSanal KalıtımÖzet - Çalışan Hiyerarşisi10STL Genel Bakış
STL Genel Bakış ve FelsefesiSTL KonteynerleriİteratörlerSTL AlgoritmalarıFunctor'lar ve Lambda İfadeleriÖzet - Kelime Frekansı13Tasarım Kalıpları 1. Bölüm
Tasarım Kalıplarına GirişSingleton KalıbıFactory ve Abstract FactoryBuilder KalıbıObserver KalıbıStrategy Kalıbı2Bellek Yönetimi
Stack ve Heap Bellekİşaretçiler ve ReferanslarDinamik Bellek (new/delete)C++'ta Akıllı İşaretçilerC++'ta RAIIÖzet - Dinamik Dizi Yöneticisi5Kapsülleme
C++'da Erişim BelirleyicilerDerinlemesine Erişim BelirleyicilerBilgi GizlemeStruct vs Classİç İçe ve Dahili SınıflarÖzet - Öğrenci Kayıt Sistemi8Çok Biçimlilik
Derleme ve Çalışma Zamanı Çok BiçimliliğiFonksiyon Aşırı YüklemeSanal Fonksiyonlara Yeniden BakışSaf Sanal FonksiyonlarSoyut SınıflarC++'ta Arayüz TasarımıDynamic Casting ve RTTIÖzet - Şekil Hesaplayıcı3Yapıcılar ve Yıkıcılar
Varsayılan YapıcıParametreli YapıcıKopya YapıcıTaşıma YapıcısıYapıcı İlklendirme ListeleriTemsilci YapıcılarYıkıcılara Derinlemesine BakışÜç / Beş / Sıfır KuralıÖzet - String Sınıfı6Operatör Aşırı Yükleme
Operatör Aşırı Yüklemeye GirişAritmetik Operatör Aşırı YüklemeKarşılaştırma Operatörü Aşırı YüklemeStream OperatörleriAtama Operatörü Aşırı Yükleme[] ve () Operatör Aşırı YüklemeTip Dönüşüm OperatörleriÖzet - Matris Sınıfı9Şablonlar
Fonksiyon ŞablonlarıSınıf ŞablonlarıŞablon ÖzelleştirmeVariadic ŞablonlarSFINAE ve Type Traits TemelleriÖzet - Generic Konteyner