Cvičenia: 10. týždeň

Cieľom cvičení je pozrieť sa na praktické využitie dedičnosti a polymorfizmu.

Tvar

  • Vytvorte triedu Tvar, ktorá bude uchovávať súradnice x a y stredu nejakého geometrického tvaru a jeho farbu.
  • Vytvorte potomkov triedy Tvar (k všetkým si dodajte potrebné inštančné premenné):
    • Kruh
    • Obdlzdnik
  • Umožnite, aby sa každý tvar vedel vykresliť na WinPane z JPaz2 frameworku:
    • kreslenie tvaru prebieha cez zavolanie metódy vykresliSa(Pane plocha)
    • metóda vykresliSa nech je definovaná v triede Tvar (pri jej volaní nad touto triedou, nech sa vypíše do System.err chybová hláška) a v triedach Kruh a Obdlznik nech je táto metóda vhodne prekrytá.
public void vykresliSa(Pane plocha)
  • Vyskúšajte metódu vykresliSa:
public static void main(String[] args) {
  WinPane plocha = new WinPane();
  Tvar t;
  if (Math.random() < 0.5) {
    t = new Kruh(...);
  } else {
    t = new Obdlznik(...);  
  }

  t.vykresliSa(plocha);
}
  • Čo sa stane, ak by trieda Tvar nemala metódu vykresliSa, ale mali by ju len triedy Kruh a Obdlznik?
  • Kde v tejto metóde main sa nachádza polymorfizmus?
  • Vytvorte metódu (v triede Tvar a prekrytú v oddedených triedach), ktorá vráti, či bod so súradnicami [x, y] je vnútorným bodom daného tvaru:
public boolean jeVnutornyBod(double x, double y)

Zoznam tvarov

  • Vytvorte triedu ZoznamTvarov ktorá bude obsahovať všetky tvary v poli typu Tvar[].
    • vytvorte vhodné metódy na pridávanie nových tvarov do zoznamu tvarov
    • vytvorte metódu nakresliVsetky(Pane plocha), ktorá vykreslí všetky tvary do zadanej kresliacej plochy Pane
    • vytvorte vlastnú triedu rozširujúcu kresliacu plochu WinPane, ktorej objekty budú v sebe udržiavať vlastný ZoznamTvarov
    • vytvorte metódu posun(double dx, double dy), ktorá posunie všetky tvary v smere zadaného vektora [dx, dy]
    • vytvorte metódu bodTvaru(double x, double y), ktorá vráti referenciu na objekt triedy Tvar, ktorého vnútorným bodom je bod so súradnicami [x, y], resp. null, ak takého objektu niet.
    • vytvorte metódu na odstránenie tvaru, zo zoznamu tvarov
    • vytvorte metódu posunSmerom(double uhol, double vzdialenost), ktorá posunie všetky tvary daným smerom o danú vzdialenosť
Štruktúra triedy ZoznamTvarov:
import sk.upjs.jpaz2.Pane;

public class ZoznamTvarov {
        //???

        public void pridajTvar(Tvar t) {
                //???
        }

        public void nakresliVsetky(Pane plocha) {
                //???
        }

        public void posun(double dx, double dy) {
                //???   
        }

        public Tvar bodTvaru(double x, double y) {
                return null;
        }

        public void odstranTvar(Tvar t) {
                //???
        }
}
Návrh triedy rozširujúcej WinPane na experimentovanie s tvarmi:
import java.awt.event.MouseEvent;

import sk.upjs.jpaz2.WinPane;

public class PlochaTvarov extends WinPane {

        private ZoznamTvarov tvary;

        private double dragX;
        private double dragY;
        private boolean tahanie = false;

        public PlochaTvarov() {
                this.tvary = new ZoznamTvarov();
        }

        @Override
        protected void onMouseClicked(int x, int y, MouseEvent detail) {
                if (detail.getButton() == MouseEvent.BUTTON1) {
                        if (detail.isAltDown()) {
                                this.tvary.pridajTvar(new Kruh(???));
                        } else {
                                this.tvary.pridajTvar(new Obdlznik(???));
                        }
                }

                if (detail.getButton() == MouseEvent.BUTTON3) {
                        Tvar naOdstranenie = this.tvary.bodTvaru(x, y);
                        if (naOdstranenie != null) {
                                this.tvary.odstranTvar(naOdstranenie);
                        }
                }

                this.clear();
                this.tvary.nakresliVsetky(this);
        }


        @Override
        protected void onMousePressed(int x, int y, MouseEvent detail) {
                if (detail.getButton() == MouseEvent.BUTTON1) {
                        this.tahanie = true;
                        this.dragX = x;
                        this.dragY = y;
                }
        }

        @Override
        protected void onMouseDragged(int x, int y, MouseEvent detail) {
                if (this.tahanie) {
                        tvary.posun(x - this.dragX, y - this.dragY);
                        this.dragX = x;
                        this.dragY = y;
                        this.clear();
                        this.tvary.nakresliVsetky(this);
                }
        }

        @Override
        protected void onMouseReleased(int x, int y, MouseEvent detail) {
                if (detail.getButton() == MouseEvent.BUTTON1) {
                        this.tahanie = false;
                }
        }
}

Tvary v súroborch

  • vymyslite spôsob, akým by ste vedeli všetky tvary uchovávať v textovom súbore
    • vytvorte metódu na uloženie tvarov do textového súboru
    • vytvorte metódu na vytvorenie zoznamu tvarov čítaním tohto textového súboru

Obsahy tvarov

  • Vytvorte vo vhodných triedach metódu obsah(), ktorá vráti obsah daného útvaru
  • Upravte triedu PlochaTvarov tak, aby po vhodnom kliknutí na tvar sa v konzole vypísal jeho obsah.

Ďalšie tvary (Tvary++)

  • Vytvorte ďalšie triedy a zvoľte im vhodných rodičov
    • Sestuholnik
    • Hviezda
  • pre fajnšmekrov: Vytvorte triedu Krivka - potomka triedy Tvar - vytvorenú myšacími udalosťami

Polymorfizmus

  • Nájdite a diskutujte o rôznych príkladoch, kde by išlo využiť dedičnosť a polymorfizmus (jednotlivé príklady môžete skúsiť aj implementovať).

Konštruktory

  • Rozdiskutujte a na príkladoch vysvetlite pravidlá:
    • Každá trieda v Jave musí mať konštruktor. Ak programátor nenapíše žiaden konštruktor, Java vytvorí implicitný konštruktor.
    • Prvý príkaz každého konštruktora je volanie konštruktora rodičovskej triedy alebo iného konštruktora danej triedy. Ak to tak nie je, Java pridá pred prvý riadok volanie bezparametrového konštruktora rodičovskej triedy (super();).

Výstava psov

Vytvoríme program, ktorý pomôže organizátorom výstavy psov. O každom súťažiacom vieme meno psa, meno majiteľa, rasu psa, vek psa a hodnotenie psa od piatich rozhodcov.

Zoznam súťažiacich sa nachádza v textovom súbore vystava.txt

  • Vytvorte triedu Pes, kde sú uložené všetky uvedené informácie o jednom súťažiacom. Trieda ZoznamPsov, ktorá bude spravovať zoznam objektov triedy Pes.
  • V triede Pes vytvorte metódu na výpis všetkých známych informácií o danom psovi.
  • Naplňte zoznam psov cez načítanie údajov z textového súboru
  • Vytvorte metódu na výpis informácií o všetkých súťažiacich psoch, využite metódu z druhého bodu.
  • Vytvorte metódu, ktorá vypočíta a vhodne uloží celkové hodnotenie psa na základe ohodnotení od rozhodcov.
  • Vytvorte metódu vypisVitaza(), ktorá vypíše informácie o víťaznom psovi, teda o psovi, ktorý má najvyššie priemerné ohodnotenie od rozhodcov.

O kuchárskej knihe a chladničke

Chcete implementovať kuchársku knižku. Každý recept má najprv zoznam surovina-mnozstvo a potom text s "algoritmom" teda poradím ako jednotlivé suroviny použiť.

  • chcete vedieť vypísať všetky recepty
  • chcete vypísať recept podľa názvu jedla
  • pre daný obsah chladničky a špajzy (zoznam surovina-množstvo) chcete vypísať tie recepty, ktoré sa dajú navariť

Aké triedy je treba vytvoriť na riešenie tejto úlohy? Čo by mali jednotlivé triedy uchovávať a akými metódami by mali disponovať?