Menu
Coddy logo textTech

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 ana seçeneğiniz vardır: kalıtım ("is-a") ve kompozisyon ("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ğ 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"; }
};

Kompozisyon, nesneleri üye olarak dahil ederek daha esnek bir ilişki oluşturur. Bir Car, bir motor olmak yerine bir Engine'e sahiptir:

class Engine {
public:
    void start() { std::cout << "Engine running\n"; }
};

class Car {
private:
    Engine engine;  // Araba bir Motora SAHİPTİR
public:
    void start() { engine.start(); }
};

Kompozisyonun temel avantajı esnekliktir. Katı bir sınıf hiyerarşisinin kısıtlamaları olmadan bileşenleri kolayca değiştirebilir, çalışma zamanında davranışı değiştirebilir veya birden fazla yeteneği birleştirebilirsiniz. Modern C++ tasarımı, çoğu durumda kalıtım yerine kompozisyonu tercih eder.

Gerçek bir "is-a" ilişkisi olduğunda ve polimorfizme ihtiyaç duyduğunuzda kalıtımı kullanın. İşlevselliği yeniden kullanmak istediğinizde veya ilişki "has-a" veya "uses-a" olarak daha iyi tanımlandığında kompozisyonu kullanın.

challenge icon

Görev

Kolay

Kompozisyonun (composition) kalıtıma (inheritance) karşı ne zaman kullanılacağını gösteren bir bilgisayar sistemi simülatörü oluşturalım. Bir bileşen olmak yerine bileşenlere sahip olan (kompozisyon) bir bilgisayarı modelleyeceksiniz ve kompozisyonun çalışma zamanında parçaları değiştirme esnekliğini nasıl sağladığını göreceksiniz.

Kodunuzu üç dosya halinde düzenleyeceksiniz:

  • Components.h: Bir bilgisayarın içerebileceği bireysel bileşenleri tanımlayın.

    Özel (private) std::string model ve int cores alanlarına sahip bir CPU sınıfı oluşturun. Her iki değeri de alan bir yapıcı (constructor), CPU [model] processing with [cores] cores yazdıran bir process() metodu ve bir getModel() metodu sağlayın.

    Özel bir int sizeGB alanına sahip bir Memory sınıfı oluşturun. Bir yapıcı, Loading data into [sizeGB]GB RAM yazdıran bir load() metodu ve bir getSize() metodu sağlayın.

    Özel std::string type ("SSD" veya "HDD" gibi) ve int capacityGB alanlarına sahip bir Storage sınıfı oluşturun. Bir yapıcı, Reading from [capacityGB]GB [type] yazdıran bir read() metodu ve her iki alan için de getter metodları sağlayın.

  • Computer.h: Bileşenleri birleştirmek için kompozisyon kullanan bir Computer sınıfı tanımlayın.

    Computer sınıfınız özel üye nesnelere sahip olmalıdır: bir CPU, bir Memory ve bir Storage. Bu bileşenleri parametrelerden başlatmak için yapıcı başlatma listesini (constructor initialization list) kullanın.

    Şu metodları uygulayın:

    • boot()Booting computer... yazdırır, ardından her biri ayrı satırlarda olmak üzere bellekte load(), depolamada read() ve CPU'da process() metodlarını çağırır.
    • specs() — bilgisayarın özelliklerini şu formatta yazdırır:
      Computer Specs:
      - CPU: [model] ([cores] cores)
      - RAM: [size]GB
      - Storage: [capacity]GB [type]
  • main.cpp: Altı girişi okuyun (her biri ayrı bir satırda):
    1. CPU model adı (string)
    2. CPU çekirdek sayısı (integer)
    3. GB cinsinden bellek boyutu (integer)
    4. Depolama türü (string, örneğin "SSD")
    5. GB cinsinden depolama kapasitesi (integer)
    6. Bir komut: "boot" veya "specs"

    Bileşen nesnelerini oluşturun, ardından kompozisyon kullanarak bir Computer oluşturun. Komuta bağlı olarak boot() veya specs() metodunu çağırın.

Örneğin, Intel i7, 8, 16, SSD, 512 ve boot girişleri ile:

Booting computer...
Loading data into 16GB RAM
Reading from 512GB SSD
CPU Intel i7 processing with 8 cores

AMD Ryzen, 6, 32, HDD, 1000 ve specs girişleri ile:

Computer Specs:
- CPU: AMD Ryzen (6 cores)
- RAM: 32GB
- Storage: 1000GB HDD

Computer sınıfının herhangi bir bileşenden kalıtım almadığına, aksine onları içerdiğine dikkat edin. Bu "sahip olma" (has-a) ilişkisi, farklı bileşen kombinasyonlarına sahip bilgisayarları kolayca oluşturabileceğiniz veya daha sonra setter metodları eklerseniz bileşenleri değiştirebileceğiniz anlamına gelir. Bu esneklik, kompozisyonun kalıtıma göre temel avantajıdır.

Kopya kağıdı

Sınıflar arasındaki ilişkileri tasarlarken, kalıtım ("is-a" - bir ...'dır) ve kompozisyon ("has-a" - bir ...'ya sahiptir) arasında seçim yapın.

Kalıtım, sınıflar arasında sıkı bir bağ (tight coupling) oluşturur:

class Vehicle {
public:
    virtual void start() { std::cout << "Starting vehicle\n"; }
};

class Car : public Vehicle {
public:
    void start() override { std::cout << "Starting car\n"; }
};

Kompozisyon, nesneleri üye olarak dahil ederek esnek ilişkiler oluşturur:

class Engine {
public:
    void start() { std::cout << "Engine running\n"; }
};

class Car {
private:
    Engine engine;  // Car HAS an Engine
public:
    void start() { engine.start(); }
};

Hangisi ne zaman kullanılmalı:

  • Polimorfizme ihtiyaç duyduğunuz gerçek "is-a" ilişkileri için kalıtım kullanın
  • İşlevselliği yeniden kullanmak veya "has-a"/"uses-a" ilişkileri için kompozisyon kullanın
  • Modern C++ tasarımı, esnekliği nedeniyle kompozisyonu tercih eder; bileşenleri değiştirebilir, çalışma zamanında davranışı değiştirebilir ve katı hiyerarşiler olmadan yetenekleri birleştirebilirsiniz

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;  // GB cinsinden bellek boyutu
    
    string storageType;
    cin >> storageType;  // Depolama türü (örneğin, "SSD")
    
    int storageCapacity;
    cin >> storageCapacity;  // GB cinsinden depolama kapasitesi
    
    string command;
    cin >> command;  // Komut: "boot" veya "specs"

    // TODO: Bileşen nesnelerini oluşturun (CPU, Memory, Storage)
    
    // TODO: Kompozisyon (composition) kullanarak bir Computer nesnesi oluşturun
    
    // TODO: Komuta bağlı olarak boot() veya specs() fonksiyonunu çağırın

    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