Menu
Coddy logo textTech

Kompozisyon ve Kalıtım

Coddy'nin Dart Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 82 / 110.

Kalıtımın bir "is-a" (bir ...-dır) ilişkisi oluşturduğunu öğrendiniz - bir Dog bir Animal'dır. Ancak başka bir güçlü yaklaşım daha vardır: bir "has-a" (bir ...-ya sahiptir) ilişkisi oluşturan kompozisyon. Bir sınıf, davranışı miras almak yerine diğer sınıfların örneklerini içerir ve işi onlara devreder.

Bir Car sınıfını düşünün. Kalıtım ile bir Engine sınıfını genişletmeye çalışabilirsiniz - ancak bir araba bir motor değildir, bir motora sahiptir:

class Engine {
  void start() => print('Engine started');
}

class Car {
  final Engine _engine = Engine();  // Kompozisyon: Araba bir Motora SAHİPTİR
  
  void start() {
    _engine.start();  // Motora devret
    print('Car is ready to drive');
  }
}

void main() {
  var car = Car();
  car.start();
}

Kompozisyonun temel avantajı esnekliktir. Kalıtım ile tek bir üst sınıfa bağlı kalırsınız. Kompozisyon ile birden fazla bileşeni birleştirebilir ve hatta bunları çalışma zamanında değiştirebilirsiniz:

class ElectricEngine {
  void start() => print('Electric motor humming');
}

class HybridCar {
  Engine? _gasEngine;
  ElectricEngine? _electricEngine;
  
  HybridCar({bool useElectric = false}) {
    if (useElectric) {
      _electricEngine = ElectricEngine();
    } else {
      _gasEngine = Engine();
    }
  }
}

Yaygın bir ilke "kalıtım yerine kompozisyonu tercih et" şeklindedir. Gerçek bir "is-a" ilişkisi olduğunda ve polimorfizme ihtiyaç duyduğunuzda kalıtımı kullanın. Davranışı sıkı bağlılık (tight coupling) olmadan yeniden kullanmak istediğinizde veya bir nesne birden fazla kaynaktan yeteneklere ihtiyaç duyduğunda kompozisyonu kullanın.

challenge icon

Görev

Kolay

Kompozisyon (composition) kullanarak bir bilgisayar sistemi oluşturalım! Bir bilgisayarı parçalarından miras alacak şekilde tasarlamak yerine, ayrı bileşen sınıfları oluşturacak ve bunları bir araya getireceksiniz - çünkü bir bilgisayarın bir CPU'su vardır ve belleği (memory) vardır; bilgisayar bir CPU veya bellek değildir.

Kodunuzu üç dosyada organize edeceksiniz:

  • components.dart: Bilgisayar parçalarını temsil eden iki bileşen sınıfı oluşturun:
    • String brand ve double speedGHz özelliklerine sahip bir CPU sınıfı. Şu dizeyi döndüren bir process() metodu ekleyin: '$brand processing at ${speedGHz}GHz'
    • int sizeGB özelliğine sahip bir Memory sınıfı. Şu dizeyi döndüren bir load() metodu ekleyin: 'Loading ${sizeGB}GB of data'
  • computer.dart: Bileşenleri birleştirmek için kompozisyon kullanan bir Computer sınıfı oluşturun. Bilgisayarınız şunları yapmalıdır:
    • Bir String name alanına sahip olmalı
    • Bir CPU ve bir Memory örneği içermeli (kompozisyon - bilgisayar bu parçalara SAHİPTİR)
    • Her iki bileşeni de dahili olarak oluşturmak için gerekli tüm değerleri yapıcı metodu (constructor) aracılığıyla kabul etmeli
    • Her iki bileşene görev devreden (delegate) ve üç satır yazdıran bir boot() metoduna sahip olmalı: bilgisayarın adı ve ardından ' starting...', sonra CPU'nun process metodunun sonucu, ardından Memory'nin load metodunun sonucu
    • Sistemi tanımlayan bir dize döndüren specs() metoduna sahip olmalı: '$name: ${cpu.brand} ${cpu.speedGHz}GHz, ${memory.sizeGB}GB RAM'
  • main.dart: Dosyalarınızı içe aktarın (import) ve kompozisyonun işleyişini gösterin:
    • 3.5 GHz hızında çalışan 'Intel' CPU'ya ve 16 GB belleğe sahip, 'Workstation' adında bir Computer oluşturun
    • boot() metodunu çağırın
    • specs() metodunun sonucunu yazdırın

Computer sınıfının CPU veya Memory sınıflarını genişletmediğine (extend), aksine onları içerdiğine ve işi onlara devrettiğine dikkat edin. Bu, kompozisyonun oluşturduğu "has-a" (sahip olma) ilişkisidir!

Beklenen çıktı:

Workstation starting...
Intel processing at 3.5GHz
Loading 16GB of data
Workstation: Intel 3.5GHz, 16GB RAM

Kendin dene

import 'computer.dart';

void main() {
  // TODO: "Workstation" adında bir Computer oluşturun:
  // - 3.5 GHz hızında çalışan Intel CPU
  // - 16 GB bellek

  // TODO: boot() metodunu çağırın

  // TODO: specs() sonucunu yazdırın
}
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