Arvutiteaduse instituut
  1. Kursused
  2. 2024/25 sügis
  3. Objektorienteeritud programmeerimine (IT mitteinformaatikutele) (LTAT.SO.003)
EN
Logi sisse

Objektorienteeritud programmeerimine (IT mitteinformaatikutele) 2024/25 sügis

  • Kodutööd ja praktikumid
  • Loengud
  • Kursuse korraldus
  • IDE juhendid
  • Silumisest

5. praktikum. Harjutused.

NB! Praktikumiülesandeid antakse alati varuga, et ka kõige kiirematel/kogenumatel lahendajatel jätkuks tegevust. Seega pole mõtet kurvastada, kui te ei jõua kõiki lahendada.

1. Lõbustuspargi simulaator

Selles ülesandes loome mitu lõbustuspargiteemalist klassi, millega saab uurida lõbustuspargi külastusi, piletitulu ja vanuspiirangute mõju. Selle tarvis tekitame külastaja klassi, mille isend oskab erinevaid lõbustusi külastada ja toimunud sündmused salvestada.

1.1. Looge aluskood

Selles ülesandes tuletame meelde isendiväljad, konstruktorid ja meetodid. Hilisemad ülesanded muudavad ja täiendavad kirjutatud aluskoodi.

  • Looge klass Külastaja.
    • Lisage privaatne isendiväli külastuseKirjeldused, mis on List<String> tüüpi. Algväärtustage külastuseKirjeldused konstruktoris - looge seal selleks tarbeks uus ArrayList<String> isend.
    • Lisage void meetod lisaKirjeldus, mis võtab parameetriks sõne. Meetod lisab parameetriks antud sõne külastuseKirjeldused listi.
    • Lisage meetod kõikKirjeldused, mis tagastab külastuseKirjeldused.
  • Looge klass Vaateratas.
    • Lisage void meetod lõbusta, mis võtab parameetriks Külastaja isendi. Meetod lisab külastajale kirjelduse "külastasin vaateratast".
  • Looge klass Lõbustuspark.
    • Lisage privaatne isendiväli lõbustus, mis on Vaateratas tüüpi. Lisage konstruktor, mille parameetri kaudu saab lõbustuse väärtustada.
    • Lisage void meetod alustaSeiklust, mis võtab parameetriks Külastaja isendi. Meetod väljastab ekraanile "alustan seiklust", kutsub välja lõbustuse lõbusta meetodi ja siis väljastab külastaja kõik kirjeldused.
  • Looge klass Test, kus on ainult peameetod. Peameetodis tee järgnevat:
    • Looge isend Vaaterattast;
    • Looge isend Lõbustuspargist, kasutades olemasolevat vaateratast;
    • Looge isend Külastajast;
    • Pange külastaja lõbustusparki seiklema.

1.2. Kasutage liidest

Selles ülesandes tuletame meelde liidese kõige lihtsama kasutusjuhu. Loome uue lõbustuse ja muudame lõbustusparki, nii et seal saab ainult vaateratta asemel kõiki sobilikke lõbustusi kasutada.

  • Looge klass Lasketiir.
    • Lisage void meetod lõbusta, mis võtab parameetriks Külastaja isendi. Kasutage Math.random ja genereerige täisarv vahemikus 0-20. Meetod lisab külastajale kirjelduse "tabasin lasketiirus N sihtmärki", kus N on genereeritud arv.
  • Looge liides Lõbustus. Liides kirjeldab void meetodit lõbusta, mis võtab parameetriks Külastaja isendi.
  • Muutke Vaateratast ja Lasketiiru, nii et nad realiseerivad liidest Lõbustus.
  • Muutke Lõbustusparki:
    • Muutke isendiväli lõbustus tüüp listiks, mis hoiab Lõbustusi. Nimetage isendiväli ümber: lõbustused.
    • Muutke konstruktorit nii, et antakse ette List<Lõbustus>, mitte üksik lõbustus.
    • Muutke alustaSeiklust meetodit, nii et külastaja läbib järjest kõik lõbustused.
  • Muutke Test peameetodit:
    • Looge isend Lasketiirust;
    • Lõbustuspargi loomisel andke argumendiks list, milles on vaateratas ja lasketiir.

1.3. Kohandage kangekaelset klassi

Meil on tihti vaja kasutada klasse, mida me ise muuta ei saa (nt Java sisse-ehitatud tüübid ja kood, mis on kirjutatud teiste ettevõtete poolt). Mõnikord on vaja panna mõni selline klass realiseerima mingit enda liidest. Sellisel juhul saab tekitada uue klassi, mis "mähib" olemasoleva klassi isendi ja kohandab ta vajaliku liidese realisatsiooniks, delegeerides põhitöö olemasolevale klassile. Seda tehnikat kutsutakse adapter pattern.

  • Lisage enda koodi järgnev klass. Seda klassi ei tohi muuta (sh ei tohi lisada liideseid ega meetodeid).
public class Kloun {
  private String nimi;
  public Kloun(String nimi) {
    this.nimi = nimi;
  }
  public void esine(Külastaja külastaja) {
    külastaja.lisaKirjeldus("nägin klouni nimega " + nimi);
  }
}
  • Looge klass LõbustavKloun, mis realiseerib liidest Lõbustus.
    • Lisage privaatne Kloun tüüpi isendiväli kloun ja loo konstruktor, mille parameetri kaudu saab selle väärtustada.
    • Realiseerige meetod lõbusta. Meetod kutsub klouni esinemise meetodit.
  • Muutke Test peameetodit. Looge Klouni isend (argumendiks andke enda lemmik klouninimi). Kasutage LõbustavKloun klassi, et lisada kloun lõbustuspargi lõbustuste listi.

1.4. Muuda funktsionaalsust ilma klassi muutmata

Mõnikord on vaja lisada klassidele funktsionaalsust. Kui sama funktsionaalsus on vaja lisada mitmele klassile, siis ei ole praktiline koodi mitmesse klassi kopeerida-kleepida. Kui klassid realiseerivad sama liidest, saab neile hoopis liidestega trikitades koodi juurde "kleepida". Selle kohta öeldakse decorator pattern.

Selleks tuleb luua uus klass, mis realiseerib soovitud liidest, aga mis delegeerib kõik meetodid teisele sama liidest realiseeriva klassi isendile. Enne ja/või pärast delegeerimist saab decorator teha täiendavaid tegevusi.

  • Muutke Külastaja klassi. Lisage privaatne int tüüpi isendiväli vanus. Lisage vastav get-meetod. Lisage konstruktor, mille parameetri kaudu saab vanuse väärtustada.
  • Looge klass VanuseKontrollija, mis realiseerib liidest Lõbustus.
    • Lisage konstruktor, mis võtab kaks parameetrit: nõutudVanus (tüüpi int) ja delegaat (tüüpi Lõbustus). Lisage vastavad privaatsed isendiväljad ja väärtustage need konstruktoris.
    • Realiseerige meetod lõbusta. Meetodis kutsuge välja delegaadi lõbusta meetod (delegeeri ilma funktsionaalsust muutmata).
    • Täiendage lõbusta meetodit. Meetod peab kontrollima külastaja vanust. Kui külastaja vanus on nõutud vanusest väiksem, siis tuleb lisada külastajale kirjeldus "külastaja ei läbinud vanusekontrolli" ja delegaati mitte kasutada. Kui vanus on sobilik, siis tuleb kutsuda delegaadi lõbusta meetod.
  • Muutke Test peameetodit.
    • Tekitage VanuseKontrollija isend, kus nõutav vanus on 10 ja delegaat on lasketiiru isend. Pange lõbustuspargi argumendiks antavasse listi lasketiiru asemel hoopis vanusekontrollija, mis delegeerib lasketiirule.
    • Tehke algse külastaja asemel kaks külastajat, üks vanusega 9 ja teine vanusega 11. Seigelge mõlemaga lõbustuspargis. Ainult 11-aastane külastaja peaks lasketiiru jõudma.

1.5. Delegaatide ahelad

Eelmises ülesandes loodud VanuseKontrollijat saab lisaks lasketiirule ka vaateratta ja klouniga kasutada, sest VanuseKontrollija oskab delegeerida ükskõik millisele Lõbustusele. Tegelikult ei pea ta üldse lõbustusele delegeerima - delegeerida võib ka mõnele teisele delegeerijale, lõbustus võib tulla alles pärast pikka delegeerimiste ahelat.

Selles ülesandes kasutame taaskord decorator patternit ja loome TasulineLõbustus klassi. Seejärel ehitame delegeerimiste ahela - külastaja läbib kõigepealt vanusekontrolli, siis külastab lõbustust ja alles lõpus maksab piletiraha.

  • Muutke Külastaja klassi. Lisage privaatne double tüüpi isendiväli kulud. Lisage void meetod lisaKulu, mis võtab parameetriks double tüüpi kulu ja suurendab selle võrra kulude isendivälja. Lisage meetod kuludeSumma, mis tagastab kulude isendivälja väärtuse.
  • Muutke Lõbustuspark klassi, nii et pärast kõigi lõbustuste külastamist väljastatakse ka lõbutsemisel tehtud kulutuste summa.
  • Looge klass TasulineLõbustus, mis realiseerib liidest Lõbustus.
    • Lisage konstruktor, mis võtab kaks parameetrit: hind (tüüpi double) ja delegaat (tüüpi Lõbustus). Lisage vastavad privaatsed isendiväljad ja väärtustage need konstruktoris.
    • Realiseerige meetod lõbusta. Meetod kutsub delegaadi lõbusta meetodi ja pärast selle lõpetamist lisab külastajale ettemääratud kulu ja kirjelduse "tasusin külastuse eest " + hind.
  • Muutke Test peameetodit.
    • Tekitage TasulineLõbustus isend, kus hind on 2.25 ja delegaat on vaateratta isend. Kasutage lõbustuspargi argumendiks antavas listis vaateratta asemel tasulist vaateratast.
    • Tekitage TasulineLõbustus isend, kus hind on 1.5 ja delegaat on lasketiiru isend. Andke VanuseKontrollija argumendiks lasketiiru asemel tasuline lasketiir (vanusekontrollija delegeerib tasulisele külastusele, mis delegeerib lasketiirule).
    • Kirjeldage kommentaaris, mis juhtuks, kui hoopis TasulineLõbustus delegeeriks vanusekontrolliga lasketiirule (objektid on üksteise sees teises järjekorras). Kuidas koodi käitumine muutuks?

2. Failipuu läbimine

Javas on sisseehitatud meetod Files.walkFileTree, mis läbib rekursiivselt etteantud failisüsteemi kausta ja kõik selles sisalduvad failid. Iga leitud kausta ja faili kohta antakse meetodi argumendiks antud vaatleja-objektile teada.

Seotud javadoc:
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/FileVisitor.html
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/Path.html
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/Files.html

Kui kompilaator hakkab exceptionite teemal virisema ("unhandled exception .."), siis lisage selle meetodi päisesse deklaratsioon throws Exception. (Kui teie IDE soovitab selle asemel try-catch plokke kasutada, siis ära teda kuula.)

public static void main(String[] args) throws Exception {
}

2.1. Failide väljastamine

Selles ülesandes kasutame Files.walkFileTree meetodit, et väljastada ekraanile kõik etteantud kaustas olevad failid.

  • Looge klass FailiVaatleja, mis realiseerib liidese FileVisitor<Path>.
    • Kõigi FileVisitor liidese meetodite tagastustüüp on FileVisitResult. Meie programmis on sobilik tagastada kõigis liidese meetodites FileVisitResult.CONTINUE.
    • Väljastage visitFile meetodis parameetriga ette antud failinimi ekraanile.
  • Looge klass FailiTest, kus on peameetod.
    • Kasutage käsureal sisestatud kaustanime. Loo sellest Path objekt, kasutades Path.of meetodit. Käsurea parameetritest oli juttu ka 2. praktikumis. (Kui sul on vana Java versioon, siis kasuta Path.of asemel Paths.get.)
    • Kontrollige, et loodud tee on kaust, kasutades Files.isDirectory meetodit. Kui käsureal sisestatud asukoht ei viita kaustale, siis väljasta veateade ja lõpeta programmi töö (return peameetodist).
    • Looge FailiVaatleja isend.
    • Kutsuge Files.walkFileTree meetod. Andke argumentideks loodud tee ja failivaatleja. Käivitage programm ja veenduge, et failivaatleja väljastab etteantud kausta sisu, selles olevate kaustade sisud jne.

2.2. Failide sorteerimine

Selles ülesandes täiendame oma failinimede väljastajat, nii et nimed väljastatakse sorteeritud järjekorras. Sorteerimise järjekorra määramiseks kasutame Comparator<T> liidest.

Comparator liidese javadoc: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Comparator.html

  • Muutke FailiVaatleja klassi. Lisage privaatne List<String> tüüpi isendiväli failiNimed. Väärtustage see konstruktoris uue ArrayList<String> isendiga. Lisage vastav get-meetod.
  • Muutke visitFile meetodit, nii et iga külastatud fail lisatakse failiNimed listi. Path objekti võib sõneks teisendada, kasutades toString meetodit. Ärge siin meetodis midagi ekraanile väljastage.
  • Muutke FailiTest peameetodit. Pärast walkFileTree meetodi lõppu sorteeri failivaatlejasse kogunenud failide nimed ja väljastage need ekraanile. Sorteerimiseks kasutage Collections.sort meetodit. Veenduge, et nimed on tähestikujärjekorras.
  • Lisage klass NimeVõrdleja, mis realiseerib liidest Comparator<String> (toimib väga sarnaselt Comparable liidesega). Realiseerige compare meetod nii, et sõned sorteeritakse tavalisest vastupidises järjekorras (["a", "b", "c"] vs ["c", "b", "a"]). Vihje: Comparator realiseerimiseks peab looma ainult compare meetodi (ära default meetodeid üle kirjuta).
  • Muutke peameetodis Collections.sort väljakutset, nii et sorteerimisalgoritm kasutaks teie loodud NimeVõrdlejat (Collections.sort(List<T>, Comparator<T>)). Veenduge, et nüüd sorteeritakse failide nimed tähed-enne-numbreid.
  • Arvutiteaduse instituut
  • Loodus- ja täppisteaduste valdkond
  • Tartu Ülikool
Tehniliste probleemide või küsimuste korral kirjuta:

Kursuse sisu ja korralduslike küsimustega pöörduge kursuse korraldajate poole.
Õppematerjalide varalised autoriõigused kuuluvad Tartu Ülikoolile. Õppematerjalide kasutamine on lubatud autoriõiguse seaduses ettenähtud teose vaba kasutamise eesmärkidel ja tingimustel. Õppematerjalide kasutamisel on kasutaja kohustatud viitama õppematerjalide autorile.
Õppematerjalide kasutamine muudel eesmärkidel on lubatud ainult Tartu Ülikooli eelneval kirjalikul nõusolekul.
Courses’i keskkonna kasutustingimused