Objektovo orientované programovanie

Zadanie 6: Správca skladu pre OOP

Cieľom tohto zadania je vytvoriť aplikáciu pre správu produktov v sklade a precvičiť si základné koncepty objektovo-orientovaného programovania v Jave – prácu s objektmi, zapuzdrenie (encapsulation), dedičnosť (inheritance), polymorfizmus, prácu s kolekciami a bezpečné chytanie a vyhadzovanie výnimiek.

Tvoja úloha

Postupuj podľa nasledovných krokov. Tvoj kód musí byť striktne v balíku oop.zadanie6.

[!WARNING] Dôležité upozornenie pre hodnotenie: Je extrémne dôležité, aby si do bodky dodržiaval požadované názvy súborov, tried a všetkých metód či atribútov. Akékoľvek preklepy alebo zmeny (napr. iný názov funkcie) spôsobia zlyhanie automatických testov, čo vedie k strate bodov! Vo svojom kóde taktiež neustále dodržuj základné princípy OOP (viditeľnosť atribútov cez private, prístupové gettery a settery, a korektné využitie dedičnosti).

  1. Abstraktná trieda Product

  2. Podtriedy PerishableProduct a ElectronicProduct

  3. Rozhranie Discountable a spracovanie zliav

  4. Zastrešenie v triede Warehouse

  5. Výnimky ProductNotFoundException, ProductAlreadyExistsException

Diagram tried (Class Diagram)

Diagram tried

[!IMPORTANT] Všetky atribúty (-) musia byť private. Prístup k nim je výhradne cez gettery a settery.


Referencia API – Ako volať jednotlivé metódy

Nižšie nájdeš presné signatúry konštruktorov a metód, ako ich testy volajú. Dodržuj presne tieto názvy!

1. Product

// Konštruktor (volá sa cez super(...) z podtried)
public Product(String id, String name, double price)

// Gettery
public String getId()
public String getName()
public double getPrice()

// Setter
public void setPrice(double price)

// Porovnávanie podľa ID
public boolean equals(Object o)
public int hashCode()

// Textová reprezentácia
public String toString()

2. PerishableProduct

// Konštruktor
PerishableProduct pp = new PerishableProduct("P1", "Jablko", 0.5, 7);

// Getter a Setter pre expirationDays
int days = pp.getExpirationDays();   // → 7
pp.setExpirationDays(10);            // zmení na 10

// Zdedené metódy z Product fungujú rovnako
String id = pp.getId();              // → "P1"

3. ElectronicProduct

// Konštruktor
ElectronicProduct ep = new ElectronicProduct("E1", "TV", 500.0, 24);

// Getter a Setter pre warrantyMonths
int months = ep.getWarrantyMonths();  // → 24
ep.setWarrantyMonths(36);            // zmení na 36

// Aplikovanie zľavy (z rozhrania Discountable)
ep.applyDiscount(20);                // → cena sa zníži o 20%
ep.applyDiscount(0);                 // → ignoruje sa (mimo rozsahu (0, 100>)
ep.applyDiscount(-5);                // → ignoruje sa
ep.applyDiscount(105);               // → ignoruje sa
ep.applyDiscount(100);               // → cena bude 0.0

4. Discountable (rozhranie / interface)

// Jediná metóda, ktorú musí ElectronicProduct implementovať
void applyDiscount(double percentage);

5. Warehouse

// Konštruktor
Warehouse warehouse = new Warehouse();

// Pridanie produktu
warehouse.addProduct(new PerishableProduct("P1", "Mlieko", 1.5, 5));
warehouse.addProduct(new ElectronicProduct("E1", "Myš", 20.0, 24));

// Počet produktov
int count = warehouse.getProductCount();  // → 2

// Pridanie duplicitného produktu (rovnaké ID) → vyhodí výnimku
warehouse.addProduct(new PerishableProduct("P1", "Iné mlieko", 2.0, 3));
// → vyhodí ProductAlreadyExistsException

// Odobranie produktu podľa ID (vyhodí výnimku ak neexistuje)
warehouse.removeProduct("P1");            // → OK, count = 1
warehouse.removeProduct("NEEXISTUJE");    // → vyhodí ProductNotFoundException

6. ProductNotFoundException

// Konštruktor s chybovou správou
throw new ProductNotFoundException("Product s ID 'X1' sa v sklade nenachádza.");

// Chytanie výnimky
try {
    warehouse.removeProduct("X1");
} catch (ProductNotFoundException e) {
    System.out.println(e.getMessage()); // správa musí obsahovať ID produktu
}

7. ProductAlreadyExistsException

// Konštruktor s chybovou správou
throw new ProductAlreadyExistsException("Product s ID 'P1' sa v sklade už nachádza.");

// Chytanie výnimky
try {
    warehouse.addProduct(new PerishableProduct("P1", "Duplicita", 1.0, 5));
} catch (ProductAlreadyExistsException e) {
    System.out.println(e.getMessage()); // správa musí obsahovať ID produktu
}

Štruktúra projektu

Tvoje riešenie musí striktne dodržiavať nasledovnú adresárovú štruktúru v balíku oop.zadanie6. Všetky zdrojové kódy musia byť v priečinku src/:

zadanie6/
├── .idea
│   └── ...
├── src/
│   └── oop/
│       └── zadanie6/
│           ├── Discountable.java
│           ├── ElectronicProduct.java
│           ├── PerishableProduct.java
│           ├── Product.java
│           ├── ProductAlreadyExistsException.java
│           ├── ProductNotFoundException.java
│           └── Warehouse.java
├── test/
│   └── oop/
│       └── zadanie6/
│           └── StudentInventoryTest.java        
├── diagramTried.png
├── zadanie6.iml
└── ....

Ako spustiť testy

Pre správne spustenie testov sa uisti, že si projekt otvoril správne v IntelliJ IDEA.

Cez IntelliJ IDEA


Dodatočné informácie

Súčasťou zadania je aj niekoľko unit testov. Pre unit testy je použitá knižnica org.junit.jupiter:junit-jupiter:5.14.3.

Do riešenia môžete doplniť vlastný testovací kód. Ale hodnotené bude len vypracovanie.

Použite Javu verzie 25.

Odovzdajte komprimovaný projekt vo formáte .zip!

Za riešenie môžete získať 5 bodov.