Agregasyon vs Kompozisyon
Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 48 / 87.
Hem toplama (aggregation) hem de kompozisyon (composition) "has-a" ilişkisi biçimleridir, ancak bir kritik noktada birbirlerinden ayrılırlar: sahiplik ve yaşam döngüsü bağımlılığı.
Kompozisyonda (composition), içerilen nesne kapsayıcıdan bağımsız olarak var olamaz. Kapsayıcı yok edildiğinde, parçaları da yok edilir. Bir House ve onun Room nesnelerini düşünün; odalar ev olmadan var olmazlar:
class House {
private Room[] rooms;
public House(int numRooms) {
rooms = new Room[numRooms];
for (int i = 0; i < numRooms; i++) {
rooms[i] = new Room(); // House, odaları oluşturur ve onlara sahiptir
}
}
}Agregasyon (aggregation) yapısında, içerilen nesne bağımsız olarak var olabilir. Kapsayıcı, nesneyi kullanır ancak onun yaşam döngüsünü kontrol etmez. Bir Team ve onun Player nesnelerini düşünün; oyuncular bir takım olmasa bile varlıklarını sürdürürler:
class Team {
private List<Player> players;
public Team() {
players = new ArrayList<>();
}
public void addPlayer(Player player) {
players.add(player); // Takım mevcut oyuncuları kullanır
}
}Temel ayrım: kompozisyonda (composition), kapsayıcı kendi parçalarını dahili olarak oluşturur. Agregasyonda (aggregation), nesneler dışarıdan aktarılır. Bir Team silindiğinde, Player nesneleri hala var olmaya devam eder. Bir House silindiğinde, Room nesneleri de yok olur.
Görev
KolayHem toplama (aggregation) hem de kompozisyonu (composition) gösteren bir üniversite kurs sistemi kuralım. Bir Course nesnesinin kendi Lecture nesnelerine nasıl sahip olduğunu (kompozisyon), bağımsız olarak var olan Professor nesnelerine ise sadece nasıl referans verdiğini (toplama) göreceksiniz.
Kodunuzu dört dosya halinde düzenleyeceksiniz:
Professor.java: Herhangi bir kurstan bağımsız olarak var olabilen bir profesörü temsil eden bir sınıf oluşturun. Bir Professor sınıfının iki özel (private) alanı vardır:name(String) vedepartment(String). Her iki alanı da başlatan bir yapıcı (constructor) ve her biri için getter metotları ekleyin.toString()metodunu şu sonucu döndürecek şekilde geçersiz kılın (override):"Prof. " + name + " (" + department + ")"Lecture.java: Sadece bir kurs dahilinde anlam ifade eden bir dersi temsil eden bir sınıf oluşturun. Bir Lecture sınıfının iki özel alanı vardır:topic(String) vedurationMinutes(int). Bir yapıcı ve getter metotları ekleyin.toString()metodunu şu sonucu döndürecek şekilde geçersiz kılın:"Lecture: " + topic + " (" + durationMinutes + " min)"Course.java: Her iki ilişkiyi de burada göstereceksiniz! Bir Course sınıfının üç özel alanı vardır:title(String),professor(Professor - toplama) velectures(bir Lecture nesneleri dizisi - kompozisyon).Yapıcı metot; kurs başlığını, bir Professor nesnesini (dışarıdan aktarılan - toplama) ve ders sayısını alır. Yapıcı metodun içinde, Lecture dizisini oluşturun ve içini yeni Lecture nesneleriyle doldurun.
iindeksindeki her bir ders için, konuyu"Topic " + (i + 1)ve süreyi45dakika olarak ayarlayarak oluşturun. Bu dahili oluşturma işlemi kompozisyonu gösterir.Çok satırlı bir String döndüren bir
getInfo()metodu ekleyin:Course: [title] Instructor: [professor.toString()] Lectures: [number of lectures]Ayrıca, her dersin toString() sonucunu kendi satırında döndüren bir
listLectures()metodu ekleyin.Main.java: Her şeyi bir araya getirin! Dört girdi alacaksınız: profesör adı (String), profesör bölümü (String), kurs başlığı (String) ve ders sayısı (int).Önce, verilen ad ve bölümle bir Professor oluşturun—bu profesör bağımsız olarak var olur. Ardından, başlığı, profesörü (toplama) ve ders sayısını (kurs kendi derslerini dahili olarak oluşturacaktır - kompozisyon) aktararak bir Course oluşturun.
getInfo()sonucunu yazdırın, ardından boş bir satır yazdırın ve sonralistLectures()sonucunu yazdırın.
Sırasıyla dört girdi alacaksınız: profesör adı, bölüm, kurs başlığı ve ders sayısı.
Temel farka dikkat edin: Professor dışarıda oluşturulur ve Course içine aktarılır (toplama—profesör başka kurslar da verebilir veya bu kurs olmadan da var olabilir). Lecture nesneleri ise Course yapıcısı içinde oluşturulur (kompozisyon—özel olarak bu kursa aittirler ve bu kurs olmadan var olmazlar).
Kopya kağıdı
Hem aggregation hem de composition, sahiplik ve yaşam döngüsü bağımlılığı açısından farklılık gösteren "has-a" ilişkileridir.
Composition: İçerilen nesne, kapsayıcıdan bağımsız olarak var olamaz. Kapsayıcı yok edildiğinde, parçaları da yok edilir. Kapsayıcı, parçalarını dahili olarak oluşturur.
class House {
private Room[] rooms;
public House(int numRooms) {
rooms = new Room[numRooms];
for (int i = 0; i < numRooms; i++) {
rooms[i] = new Room(); // House creates and owns rooms
}
}
}Aggregation: İçerilen nesne bağımsız olarak var olabilir. Kapsayıcı nesneyi kullanır ancak yaşam döngüsünü kontrol etmez. Nesneler dışarıdan aktarılır.
class Team {
private List<Player> players;
public Team() {
players = new ArrayList<>();
}
public void addPlayer(Player player) {
players.add(player); // Team uses existing players
}
}Temel fark: Bir kapsayıcı silindiğinde, aggregation ile bağlı nesneler var olmaya devam eder, ancak composition ile bağlı nesneler yok edilir.
Kendin dene
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Girdileri oku
String professorName = scanner.nextLine();
String department = scanner.nextLine();
String courseTitle = scanner.nextLine();
int numberOfLectures = scanner.nextInt();
// TODO: Bir Professor nesnesi oluştur (bağımsız olarak var olur - toplama/aggregation)
// TODO: Profesörü parametre olarak geçerek bir Course nesnesi oluştur (toplama/aggregation)
// Kurs, kendi derslerini (lectures) dahili olarak oluşturacaktır (bileşim/composition)
// TODO: getInfo() sonucunu yazdır
// TODO: Boş bir satır yazdır
// TODO: listLectures() sonucunu yazdır
}
}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 DosyalarOOP'ye GirişSınıflar ve Nesnelerthis Anahtar KelimesiMetotlarAlanlar (Öznitelikler)Yapıcı MetotYapıcı Metot Aşırı YüklemeÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (extends)super Anahtar KelimesiMetot Geçersiz Kılma (@Override)Yapıcı Metot ZincirlemeObject SınıfıTekli ve Çok Seviyeli KalıtımNeden Çoklu Sınıf Kalıtımı Yok?Özet - Çalışan Hiyerarşisi7Özel Metotlar ve Object Sınıfı
toString() Metoduequals() ve hashCode()clone() MetoducompareTo() ve ComparableComparator ArayüzüÖzet - Özel Sıralama2Erişim Belirleyiciler ve Kapsülleme
Erişim Seviyelerine Genel BakışGetter ve Setter MetotlarıBilgi Gizlemefinal Anahtar KelimesiÖzet - Banka Hesabı Yöneticisi5Polimorfizm
Metot Aşırı Yükleme TemelleriMetot Geçersiz Kılma (Çalışma Zamanı)Upcasting ve Downcastinginstanceof OperatörüSoyut Sınıflar ve MetotlarÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımAgregasyon vs KompozisyonDahili, Yuvalanmış ve Anonim SınıflarEnum'lar ve Enum MetotlarıRecords (Java 16+)Sealed Classes (Java 17+)11Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıBuilder KalıbıObserver KalıbıStrategy Kalıbı14Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi3Sınıf Özellikleri ve Statik Üyeler
Instance ve Statik DeğişkenlerStatik MetotlarStatik BloklarSabitler (static final)Özet - Sayaç ve Utility6Arayüzler ve Soyut Sınıflar
Arayüzlere GirişArayüzleri UygulamaÇoklu Arayüz UygulamaArayüzlerde Default ve StaticSoyut Sınıflar ve ArayüzlerFonksiyonel ArayüzlerÖzet - Ödeme Sistemi9Generics
Generics'e GirişGeneric SınıflarGeneric MetotlarSınırlandırılmış Tip ParametreleriWildcard'lar (?, extends, super)Özet - Generic Container12Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit KalıbıYineleyici Kalıbı