
Learning Log #2: Tydzień 10-11 Zajavka – agregacja, kompozycja i kiedy klasy się przyjaźnią
Kubek kawy numer trzy dzisiaj. Słuchawki na uszach. Dzieci w końcu się uspokoiły i bawią się same. Mam może godzinę.
Tydzień 10 i 11 kursu Zajavka był… intensywny. Dwa tygodnie zajęło mi przebrnięcie przez materiał, który teoretycznie powinien zająć jeden. Ale wiesz co? I tak jestem z siebie dumna.
Dziś o tym jak klasy współpracują ze sobą w Java – o agregacji, kompozycji i relacjach które sprawiają że kod przestaje być zbiorem przypadkowych kawałków, a zaczyna być… systemem.
Gdzie jestem w kursie Java?
Oficjalnie: Tydzień 10-11 z kursu „Java w 12 tygodni Zajavka”
Realnie: Gdzieś na 13-14 tygodniu od startu (pamiętajcie – życie z dziećmi ma swoje tempo)
Postęp: ~65% kursu. Podstawy mam solidne, teraz wchodzę w zaawansowane OOP.
Czas nauki: ~8 godzin w ostatnich dwóch tygodniach (mniej niż zwykle – dzieci były częściej wymagające)
Co to jest agregacja i kompozycja?
Przez pierwszy dzień myślałam, że to jakaś magiczna zaawansowana rzecz. Potem zrozumiałam: to po prostu jak klasy trzymają inne klasy w sobie.
Najprostsza analogia – mój dom:
Agregacja = Mebli w domu
- Dom MA meble
- Meble mogą istnieć bez domu (można je przenieść)
- Dom przestaje istnieć → meble dalej są
Kompozycja = Pokoje w domu
- Dom SKŁADA SIĘ Z pokoi
- Pokoje nie mogą istnieć bez domu
- Dom przestaje istnieć → pokoje też przestają
W kodzie Java:
// AGREGACJA - słabszy związek
public class House {
private List<Furniture> furniture; // meble mogą być w innym domu
public House(List<Furniture> furniture) {
this.furniture = furniture; // dostajemy meble z zewnątrz
}
}
// KOMPOZYCJA - silny związek
public class House {
private List<Room> rooms; // pokoje należą TYLKO do tego domu
public House() {
this.rooms = new ArrayList<>();
rooms.add(new Room("Bedroom")); // tworzymy pokoje WEWNĄTRZ
rooms.add(new Room("Kitchen"));
}
}
Mój pierwszy projekt z agregacją – Family
Postanowiłam zrobić coś bliskiego sercu – system zarządzania rodziną (bo przecież mam doświadczenie 😅).
public class Person {
private String name;
private int age;
private String role; // "parent", "child"
public Person(String name, int age, String role) {
this.name = name;
this.age = age;
this.role = role;
}
public String getName() {
return name;
}
public String getRole() {
return role;
}
@Override
public String toString() {
return name + " (" + age + " years, " + role + ")";
}
}
public class Family {
private String familyName;
private List<Person> members; // AGREGACJA - osoby mogą istnieć poza rodziną
public Family(String familyName) {
this.familyName = familyName;
this.members = new ArrayList<>();
}
public void addMember(Person person) {
members.add(person);
System.out.println(person.getName() + " joined " + familyName + " family");
}
public void removeMember(Person person) {
members.remove(person);
System.out.println(person.getName() + " left the family");
}
public void showFamily() {
System.out.println(familyName + " Family:");
for (Person member : members) {
System.out.println(" - " + member);
}
}
public List<Person> getParents() {
return members.stream()
.filter(p -> p.getRole().equals("parent"))
.toList();
}
}
// Użycie:
public class Main {
public static void main(String[] args) {
Person mom = new Person("Anna", 32, "parent");
Person dad = new Person("Marek", 34, "parent");
Person child1 = new Person("Kasia", 5, "child");
Person child2 = new Person("Tomek", 3, "child");
Family smiths = new Family("Smith");
smiths.addMember(mom);
smiths.addMember(dad);
smiths.addMember(child1);
smiths.addMember(child2);
smiths.showFamily();
// Output:
// Smith Family:
// - Anna (32 years, parent)
// - Marek (34 years, parent)
// - Kasia (5 years, child)
// - Tomek (3 years, child)
}
}
Co mnie zaskoczyło?
To że osoby (Person) nie wiedzą o rodzinie (Family). Mogą istnieć osobno. Mogą być w kilku rodzinach jednocześnie (np. rozszerzona rodzina). To jest cała idea agregacji!
Kompozycja – silniejszy związek
Kompozycja to, gdy obiekt nie może istnieć bez swojego „rodzica”.
Mój przykład – Therapy Session
public class TherapySession {
private String type; // "SI", "logopeda", "pedagog"
private LocalDateTime dateTime;
private int durationMinutes;
// Konstruktor pakietowy - tylko TherapySchedule może tworzyć sesje
TherapySession(String type, LocalDateTime dateTime, int durationMinutes) {
this.type = type;
this.dateTime = dateTime;
this.durationMinutes = durationMinutes;
}
@Override
public String toString() {
return type + " therapy on " + dateTime + " (" + durationMinutes + " min)";
}
}
public class TherapySchedule {
private String childName;
private List<TherapySession> sessions; // KOMPOZYCJA
public TherapySchedule(String childName) {
this.childName = childName;
this.sessions = new ArrayList<>(); // tworzymy listę TUTAJ
}
public void addSession(String type, LocalDateTime dateTime, int duration) {
// Tworzymy sesję WEWNĄTRZ harmonogramu
TherapySession session = new TherapySession(type, dateTime, duration);
sessions.add(session);
System.out.println("Added: " + session);
}
public void showSchedule() {
System.out.println("Therapy schedule for " + childName + ":");
sessions.forEach(System.out::println);
}
public int getTotalHoursThisMonth() {
return sessions.stream()
.mapToInt(s -> s.durationMinutes)
.sum() / 60;
}
}
// Użycie:
TherapySchedule schedule = new TherapySchedule("Michaś");
schedule.addSession("SI", LocalDateTime.now().plusDays(1), 60);
schedule.addSession("Logopeda", LocalDateTime.now().plusDays(2), 45);
schedule.addSession("Pedagog", LocalDateTime.now().plusDays(3), 60);
schedule.showSchedule();
// Output:
// Therapy schedule for Michaś:
// SI therapy on 2026-02-19T14:30 (60 min)
// Logopeda therapy on 2026-02-20T10:00 (45 min)
// Pedagog therapy on 2026-02-21T15:00 (60 min)
Różnica kluczowa:
W agregacji Person jest tworzony NA ZEWNĄTRZ i przekazywany do Family.
W kompozycji TherapySession jest tworzony WEWNĄTRZ TherapySchedule.
Relacje między klasami – has-a vs is-a
To był dla mnie moment „aha!” tego tygodnia.
IS-A = dziedziczenie (inheritance)
public class Animal {
String name;
}
public class Dog extends Animal {
// Dog IS-A Animal
}
HAS-A = agregacja/kompozycja
public class Person {
String name;
}
public class House {
Person owner; // House HAS-A Person
}
Kiedy używać czego?
IS-A gdy mówimy: „X jest typem Y”
- Pies jest zwierzęciem
- Samochód elektryczny jest samochodem
- Student jest osobą
HAS-A gdy mówimy: „X ma Y” lub „X składa się z Y”
- Osoba ma adres
- Samochód ma silnik
- Harmonogram ma sesje terapii
Typowe błędy, które popełniłam
1. Mylenie agregacji z kompozycją
Błąd:
public class Family {
private List<Person> members = new ArrayList<>();
public void addMember(String name, int age) {
members.add(new Person(name, age)); // To jest kompozycja!
}
}
Poprawka:
public class Family {
private List<Person> members = new ArrayList<>();
public void addMember(Person person) { // Agregacja - dostajemy obiekt z zewnątrz
members.add(person);
}
}
2. Publiczny konstruktor w kompozycji
Błąd:
public class TherapySession {
public TherapySession(...) { } // Każdy może tworzyć sesje!
}
Poprawka:
public class TherapySession {
TherapySession(...) { } // Package-private - tylko TherapySchedule może tworzyć
}
3. Zapomnienie o null safety
Błąd:
public void showFamily() {
for (Person member : members) { // Co jeśli members jest null?
System.out.println(member);
}
}
Poprawka:
public void showFamily() {
if (members == null || members.isEmpty()) {
System.out.println("No family members");
return;
}
members.forEach(System.out::println);
}
Praktyczne zastosowanie – mój mini projekt
Zbudowałam system do śledzenia kosztów terapii (bardzo przydatne w moim życiu!).
Klasy:
Therapy– pojedyncza terapia (typ, koszt jednostkowy)TherapySession– konkretna sesja (data, czas trwania)Child– dziecko (ma listę terapii – agregacja)MonthlyReport– raport miesięczny (tworzy sesje wewnątrz – kompozycja)
public class Therapy {
private String type;
private double costPerSession;
public Therapy(String type, double costPerSession) {
this.type = type;
this.costPerSession = costPerSession;
}
public double getCostPerSession() {
return costPerSession;
}
public String getType() {
return type;
}
}
public class Child {
private String name;
private List<Therapy> therapies; // AGREGACJA
public Child(String name) {
this.name = name;
this.therapies = new ArrayList<>();
}
public void enrollInTherapy(Therapy therapy) {
therapies.add(therapy);
}
public double calculateMonthlyCost(int sessionsPerTherapy) {
return therapies.stream()
.mapToDouble(t -> t.getCostPerSession() * sessionsPerTherapy)
.sum();
}
}
Rezultat: Mam working code, który pokazuje mi że:
- 2x terapia SI po 75 zł = 600 zł/mies (8 sesji)
- 2x logopeda po 65 zł = 520 zł/mies (8 sesji)
- 1x pedagog po 60 zł = 240 zł/mies (4 sesje)
- Total: 1360 zł/mies
Bonus: Kod, który faktycznie rozwiązuje mój realny problem!
Nauka Java z życiem w tle
Jak wyglądały te dwa tygodnie:
Tydzień 10:
- Dzieci niewymagające wzmożonej uwagi = 6h nauki
- 4x po godzinie + 2h w weekend
- Zbudowałam Family system
Tydzień 11:
- Dziecko wymagające uwagi = 2h nauki
- Tylko wieczory gdy spało
- Dokończyłam Therapy cost tracker
Total: 8h na 2 tygodnie = mniej niż zwykle
Reakcja: Mogłam się stresować, że „za wolno”. Zamiast tego myślę: „8h to 8h więcej niż zero. Progress!”
Co pomaga, gdy czas jest ograniczony:
- Małe cele – nie „skończę tydzień 10”, ale „zrozumiem agregację dziś”
- Praktyczne projekty – Family, Therapy – rzeczy z mojego życia
- Notatki głosowe – gdy dziecko się budzi, a ja mam pomysł
- Akceptacja – niektóre dni = zero nauki. I to OK.
Plany na tydzień 12
Przede mną:
- Interfejsy – co to i dlaczego
- Abstrakcyjne klasy – kiedy używać
- Polimorfizm – ostatecznie zrozumieć
Kurs Java Zajavka powoli zbliża się do końca podstawowej części. Czuję że solidne fundamenty są już położone.
Dla kogo jest ten learning log?
To nie jest tutorial „jak programować w Java”. To jest real talk o nauce programowania jako mama.
Jeśli:
- Uczysz się przy dzieciach
- Masz 5-10h tygodniowo, nie 40h
- Czasem tydzień mija bez linii kodu
- Zastanawiasz się „czy to w ogóle ma sens”
To TAK, ma sens. 8h to 8h. Progress nie musi być liniowy.
Podsumowanie tygodnia 10-11
✅ Nauczyłam się: Agregacja, kompozycja, relacje między klasami
✅ Napisałam: Family system, Therapy cost tracker (working code!)
✅ Zrozumiałam: HAS-A vs IS-A, kiedy używać agregacji a kiedy kompozycji
✅ Walczę z: Null safety, poprawne projektowanie relacji
✅ Czas nauki: 8h w ciągu 2 tygodni (mniej przez chorobę dziecka)
Następny Learning Log: Tydzień 12 – interfejsy i abstrakcyjne klasy. Zapisz się do newslettera, żeby nie przegapić!
PS: Też walczysz z nauką przy dzieciach? Też masz tygodnie gdzie zero czasu? Napisz w komentarzu – przypomnimy sobie nawzajem że nie jesteśmy sami. A jeśli masz pytania o agregację, kompozycję czy Zajavka – pytaj śmiało!
Zostaw Komentarz