Kompozisyon ve Kalıtım Karşılaştırması
Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 76 / 104.
Sınıflar arasındaki ilişkileri tasarlarken iki temel seçeneğiniz vardır: kalıtım ("is-a") ve composition ("has-a"). Doğru yaklaşımı seçmek, kodunuzun esnekliğini ve sürdürülebilirliğini önemli ölçüde etkiler.
Kalıtım, sınıflar arasında sıkı bir bağımlılık oluşturur. Vehicle sınıfından kalıtım alan bir Car, bu ilişkiye kalıcı olarak bağlıdır:
class Vehicle {
public:
virtual void start() { std::cout << "Starting vehicle\n"; }
};
class Car : public Vehicle {
public:
void start() override { std::cout << "Starting car\n"; }
};Bileşim, nesneleri üyeler olarak gömer ve daha esnek bir ilişki oluşturur. Bir Car Engine olmak yerine bir Engine has:
class Engine {
public:
void start() { std::cout << "Engine running\n"; }
};
class Car {
private:
Engine engine; // Car bir Engine'e SAHİP
public:
void start() { engine.start(); }
};Bileşimin temel avantajı esnekliktir. Bileşenleri kolayca değiştirebilir, çalışma zamanında davranışı değiştirebilir veya katı bir sınıf hiyerarşisinin kısıtlamaları olmadan birden çok yeteneği birleştirebilirsiniz. Modern C++ tasarımı çoğu durumda kalıtım yerine bileşimi tercih eder.
Gerçek bir "bir-şeydir" ilişkisi olduğunda ve polimorfizme ihtiyaç duyduğunda kalıtımı kullan. İşlevselliği yeniden kullanmak istediğinde veya ilişkiyi "sahiptir" ya da "kullanır" şeklinde tanımlamak daha uygunsa kompozisyonu kullan.
Görev
KolayBir bilgisayarın kalıtım yerine bileşime ne zaman ihtiyaç duyduğunu gösteren bir bilgisayar sistemi simülatörü oluşturalım. Bir bileşen olmak yerine bileşenlere sahip olan bir bilgisayarı modelleyecek ve bileşimin parçaları çalışma zamanında değiştirme esnekliği sağladığını göstereceksin.
Kodunu üç dosya arasında düzenleyeceksin:
Components.h: Bir bilgisayarın içerebileceği bağımsız bileşenleri tanımla.Özel
CPUvestd::string modelalanlarına sahip birint coressınıfı oluştur. Her iki değeri alan bir kurucu,process()yazdıran birCPU [model] processing with [cores] coresmetodu ve birgetModel()metodu sağla.Özel bir
Memoryalanına sahip birint sizeGBsınıfı oluştur. Bir kurucu,load()yazdıran birLoading data into [sizeGB]GB RAMmetodu ve birgetSize()metodu sağla.Storage(örneğin "SSD" veya "HDD") vestd::string typealanlarına sahip birint capacityGBsınıfı oluştur. Bir kurucu,read()yazdıran birReading from [capacityGB]GB [type]metodu ve her iki alan için getter metotları sağla.Computer.h: Bileşenleri birleştirmek için bileşimi kullanan birComputersınıfı tanımla.Computersınıfın özel üye nesneleri olarak birCPU, birMemoryve birStorageiçermeli. Bu bileşenleri parametrelerden başlatmak için kurucu başlatma listesini kullan.Şu metotları uygula:
boot():Booting computer...yazdırır; ardından her birini ayrı satırda olacak şekilde bellek üzerindeload(), depolama üzerinderead()ve CPU üzerindeprocess()çağırırspecs(): bilgisayarın özelliklerini şu biçimde yazdırır:Computer Specs: - CPU: [model] ([cores] cores) - RAM: [size]GB - Storage: [capacity]GB [type]
main.cpp: Altı girdi oku (her biri ayrı bir satırda):- CPU model adı (string)
- CPU çekirdek sayısı (tam sayı)
- GB cinsinden bellek boyutu (tam sayı)
- Depolama türü (string, örneğin "SSD")
- GB cinsinden depolama kapasitesi (tam sayı)
- Bir komut: "boot" veya "specs"
Bileşen nesnelerini oluştur, ardından bileşimi kullanarak bir
Computeroluştur. Komuta bağlı olarakboot()veyaspecs()çağrısını yap.
Örneğin Intel i7, 8, 16, SSD, 512 ve boot girdileriyle:
Booting computer...
Loading data into 16GB RAM
Reading from 512GB SSD
CPU Intel i7 processing with 8 coresAMD Ryzen, 6, 32, HDD, 1000 ve specs girdileriyle:
Computer Specs:
- CPU: AMD Ryzen (6 cores)
- RAM: 32GB
- Storage: 1000GB HDDComputer sınıfının herhangi bir bileşenden kalıtım almadığına dikkat et. Bileşenleri içerir. Bu "sahiptir" ilişkisi, farklı bileşen kombinasyonlarına sahip bilgisayarları kolayca oluşturabileceğin veya setter metotları eklersen bileşenleri daha sonra değiştirebileceğin anlamına gelir. Bu esneklik, bileşimin kalıtıma göre temel avantajıdır.
Kendin dene
#include <iostream>
#include <string>
#include "Computer.h"
using namespace std;
int main() {
// Girdileri oku
string cpuModel;
getline(cin, cpuModel); // CPU model adı (boşluk içerebilir)
int cpuCores;
cin >> cpuCores; // CPU çekirdek sayısı
int memorySize;
cin >> memorySize; // Bellek boyutu GB cinsinden
string storageType;
cin >> storageType; // Depolama türü (örn., "SSD")
int storageCapacity;
cin >> storageCapacity; // Depolama kapasitesi GB cinsinden
string command;
cin >> command; // Komut: "boot" veya "specs"
// TODO: Bileşen nesnelerini oluştur (CPU, Memory, Storage)
// TODO: Kompozisyon kullanarak bir Computer nesnesi oluştur
// TODO: Komuta göre boot() veya specs() çağır
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ı11İleri Düzey OOP Kavramları
Kompozisyon ve Kalıtım KarşılaştırmasıCRTP ile Mixin YapılarıPimpl İdiyomuTür Silme (Type Erasure)Enum Sınıfları ve Güçlü TiplendirmeOOP'de İstisna YönetimiÖzel İstisna Hiyerarşileri3Yapı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 KonteynerKendi başına pratik yap: Online C++ derleyicisi