Cvičenie 9 – Triedy v OOP

Cieľom cvičení je pozrieť sa bližšie na vytváranie vlastných tried. Vlastné triedy sme vytvárali už od prvého týždňa (spomeňte si na triedu SmartTurtle) rozširovaním tried z JPAZ-u. Počnúc týmto týždňom budeme vlastné triedy vytvárať rozširovaním triedy Object (tej najzákladnejšej triedy v Jave, každá iná trieda v Jave vznikla práve jej rozšírením). Zároveň sa budeme orientovať na tvorbu tried, ktorých objekty sú určené na uchovávanie komplexných údajov. Ako archetyp pre projekty odporúčane použiť jpaz2-launcher.

Bod

Pri práci s JPAZ-om (klikanie do plochy, pozícia korytnačky, atď.), či rôznych grafických aplikáciach, by sa nám hodilo mať triedu, v ktorej by sme vedeli uchovávať informácie o jednom bode. V prípade bodu v ploche je takýto bod charakterizovanými svojimi súradnicami (x-ová a y-ová súradnica). Navrhnite a implementujte triedu Bod, ktorá bude poskytovať:

  • vhodné get/set metódy
  • vhodné konštruktory (s uvedením i bez uvedenia súradníc)
  • užitočné (public) metódy:
    • vytvorenie reťazca s informáciou o bode v tvare [100.2, 14.8]
    • nastavenie súradníc:
      • na zadané súradnice void nastav(double x, double y)
      • podľa iného bodu void nastav(Bod bod)
    • overenie, či bod obsahuje rovnaké súradnice ako iný bod:
      • boolean rovnakeSuradnice(Bod bod)
    • vzdialenosť k inému bodu:
      • double vzdialenostK(double x, double y)
      • double vzdialenostK(Bod bod)
    • zmena uchovávaných súradníc posunutím
      • void posunO(double dx, double dy)
    • vytvorí nový bod, ktorý bude obsahovať posunuté súradnice aktuálneho bodu
      • Bod posunutyBod(double dx, double dy)

Čo vypíšu tieto príkazy pred a čo po naprogramovaní metódy toString ? (Vysvetlenie zmeny správania nech ostane na cvičení utajené!)


1
2
Bod b = new Bod(100, 200);
System.out.println(b);

Na skúmanie objektov triedy Bod môžete použiť aj ObjectInspector.

Poznámka: Niektoré korytnačie metódy pracujú (vracajú/akceptujú ako parameter) objekty triedy Point2D, ktoré sú veľmi podobné objektom triedy Bod.

Zoznam bodov

Vytvorte triedu ZoznamBodov, ktorej objekty budú slúžiť na uchovávanie postupnosti bodov. Takáto postupnosť bodov môže vzniknúť napríklad naklikaním do kresliacej plochy. Budeme uchovávať zoznam bodov, nie množinu bodov – t.j. jeden bod môže byť teoreticky do zoznamu vložený viac krát. Objekty triedy ZoznamBodov nech majú metódy:

  • int dlzka() – vráti dĺžku zoznamu bodov (počet bodov)
  • void pridajBod(Bod bod) – pridá bod na koniec zoznamu bodov
  • Bod dajBod(int index) – vráti bod v zozname bodov na zadanom indexe (pozícii)
  • void vymaz() – vyprázdni zoznam bodov
  • double dlzkaSpojnic() – vráti, akú dlhú lomenú úsečku by sme dostali, ak by sme všetky body v zozname bodov postupne za sebou pospájali úsečkami
  • String toString() – vráti reťazec obsahujúci pekný výpis bodov (napr. [[10, 10], [12.5, 19], [34, 100.3]])
  • void odoberBod(int index) – odstráni bod v zozname bodov na zadanom indexe (pozícii)

Pre fajnšmekrov: Na uloženie bodov budete používať nejaké pole. Pri každom pridaní, či odobraní bodu je treba zmeniť veľkosť poľa (vytvoriť nové pole novej veľkosti). Toto je však časovo náročná operácia. Upravte preto internú implementáciu triedy tak, aby sa interné pole zväčšovalo/zmenšovalo iba po dávkach (napr. po násobkoch 20).

Nie len pre fajnškrov
Do triedy ZoznamBodov doplňte nasledujúce metódy:

  • boolean pridajBodAkSaTamNenachadza(Bod bod)
    • Do zoznamu bodov pridá Bod bod ak sa tam zatiaľ bod s rovnakými súradnicami nenachádza. Ak sa sa tam už bod nachádza (teda sme ho nepridali znova) metóda vráti false inak metóda vráti true.
  • Pridajte metódy na uloženie zoznamu bodov do súboru a načítanie v rovnakom formáte.

1
2
public void ulozDoSuboru(File subor);
public void nacitajZoSuboru(File subor);
  • Doplňte do triedy konštruktor ktorý vytvorí zoznam bodov na základe obsahu súboru.

Kurzový lístok

Vytvorte triedu KurzovyListok, ktorá bude uchovávať aktuálny kurz EUR voči iným menám. Trieda by mala poskytovať metódy:


1
2
3
public void nastavKurz(String kodMeny, double kurz);
public double vratKurz(String kodMeny);
public double prepocitaj(double suma, String kodMeny);

Rada: zvážte vytvorenie pomocnej triedy, ktorá bude uchovávať dvojicu [mena, kurz].

Pridajte metódy na uloženie kurzového lístka do súboru a zo súboru. Navrhnite si vhodný formát, tak aby ste tieto operácie čo najjednoduchšie naprogramovali.


1
2
public void ulozDoSuboru(File subor);
public void nacitajZoSuboru(File subor);

Pre fajnšmekrov: Vytvorte metódu, ktorá načíta kurzový lístok z webovej stránky banky. V prípade, že banka zverejňuje kurz na nákup a predaj, vypočítajte z týchto hodnôt stred (priemer). Na načítanie súboru z webu môžete použiť nižšie uvedenú schému:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Scanner citac = null;
try {
        URL url = new URL("https://www.csob.sk/delegate/getExchangeRatesExport?EXPORT_TYPE=CSV&DISPLAY=BANKNOTES&DATE=2017062219");
        citac = new Scanner(url.openStream(), "UTF-8");
        while (citac.hasNextLine()) {
                System.out.println(citac.nextLine());
        }
} catch (MalformedURLException e) {
        System.err.println("Chybna URL");
} catch (IOException e) {
        System.err.println("Chyba pocas spojenia so serverom.");
} finally {
        if (citac != null)
                citac.close();
}

Matice

Vytvorte triedu Matica na uloženie 2-rozmerných matíc (2-rozmerné pole zaobalené v objekte) reálnych čísel:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
public class Matica {
    // ???

    /**
     * Vytvori maticu zo samych 0 so zadanymi rozmermi
     */

    public Matica(int pocetRiadkov, int pocetStlpcov) {
        // ???
    }

    /**
     * Vytvori maticu na zaklade obsahu matice v textovom subore
     * @param subor cesta k suboru s obsahom matice
     */

    public Matica(File subor) {
        // ???
    }

    /**
     * Vrati pocet riadkov matice
     */

    public int getPocetRiadkov() {
        // ???
    }

    /**
     * Vrati pocet stlpcov matice
     * @return
     */

    public int getPocetStlpcov() {
        // ???
    }

    /**
     * Nastavi hodnotu v policku (elemente) v definovanom riadku a stlpci na
     * zadanu hodnotu.
     */

    public void nastav(int riadok, int stlpec, double hodnota) {
        // ???
    }

    /**
     * Vrati hodnotu policka (elementu) v definovanom riadku
     * a stlpci.
     */

    public double vrat(int riadok, int stlpec) {
        // ???
    }

    /**
     * Ulozi maticu do suboru
     */

    public void ulozDoSuboru(File subor) {
        // ???
    }

    /**
     * Vrati referenciu na novovytvorenu maticu, ktore je
     * suctom tejto matice a matice referencovanej z parametra
     * m. V pripade, ze scitane matice su nekompatibilne, metoda
     * nech vrati null.
     */

    public Matica scitajS(Matica m) {
        // ???
    }

        /**
         * Pre mierne pokrocilych:
         * Transformuje maticu do tvaru diagolnálnej matice
         * aplikovaním gaussovej eliminačnej metódy.
         */

        public void gem() {
                // ???
        }
}

Pri uložení matice do textového súboru odporúčame si do prvého riadku uchovať rozmery matice.


1
2
3
4
3 4
10 10 20 45
12  1 12 13
5  19 22  3

Informácie o Gaussovej eliminačnej metóde možno nájsť tu (ale určite bola na niektorom z matematických predmetov):

Pri implementácii GEM môžete uvažovať aj variant metódy s parametrom platneStlpce určujúcim koľko stĺpcov matice je „platných“. Môžete si to predstaviť ako pozíciu vertikálnej čiary, keď sa robí GEM ručne – vtedy platí platneStlpce = pocetStlpcov()-1. Pri počítaní inverznej matice by to bolo platneStlpce = pocetStlpcov()/2.