Pakolliset tehtävät on merkitty harmalla taustavärillä. Punaisella taustavärillä merkatut ovat kontrollitehtäviä, jotka näytetään ohjaajalle harjoitustilaisuudessa!
HUOM: nimeä tiedostot otsikossa olevan sanan mukaan
Toteuta luokka A
, joka tulostaa konstruktorissaan tekstin Luokan A konstruktori!
. Lisäksi luokalla on metodi String a()
, joka palauttaa tekstin "a".
public class Aakkoset { public static void main(String[] args) { A a = new A(); System.out.println("---"); System.out.println(a.a()); } }
Ohjelma tulostaa:
Luokan A konstruktori! --- a
Toteuta luokka Ab
, joka tulostaa konstruktorissaan tekstin Luokan Ab konstruktori!
. Lisäksi luokalla on metodi String b()
, joka palauttaa tekstin "b".
Luokka Ab
perii luokan A
. Toteuta konstuktori siten, että ensin kutsutaan yläluokan konstuktoria ja sitten vasta tulostetaan oma teksti.
public class Aakkoset { public static void main(String[] args) { A a = new A(); System.out.println("---"); Ab ab = new Ab(); System.out.println("---"); System.out.println(a.a()); System.out.print(ab.a()); System.out.println(ab.b()); } }
Luokan A konstruktori! --- Luokan A konstruktori! Luokan Ab konstruktori! --- a ab
Toteuta luokka Abc
samalla tavalla. Käytä oheista testiohjelmaa ja varmista, että tulostus on oikein.
public class Aakkoset { public static void main(String[] args) { A a = new A(); System.out.println("---"); Ab ab = new Ab(); System.out.println("---"); Abc abc = new Abc(); System.out.println("---"); System.out.println(a.a()); System.out.print(ab.a()); System.out.println(ab.b()); System.out.print(abc.a()); System.out.print(abc.b()); System.out.println(abc.c()); } }
Luokan A konstruktori! --- Luokan A konstruktori! Luokan Ab konstuktori! --- Luokan A konstruktori! Luokan Ab konstuktori! Luokan Abc konstruktori! --- a ab abc
Lisää projektiin rajapinta Laskuri
.
public interface Laskuri { public void kasvataArvoa(); public void vahennaArvoa(); public int getArvo(); }
Toteuta luokka Silta
, joka tietää pituutensa kokonaislukuna. Lisäksi lisää projektiin luokka Testaaja.
Seuraavat testit käyttävät luokkaa Testaaja. Tehtävää tehdessä varmista, että Testaaja.onkoValmis();
on aina pääohjelman viimeinen rivi.
Silta s = new Silta(10); if (s.getPituus() != 10) Testaaja.virhe("Pituus ei ole 10"); Testaaja.vaadiRajapinta(Silta.class, Laskuri.class); Testaaja.tarkistaAttribuutit(Silta.class); if (s.getArvo() != 0) Testaaja.virhe("Sillan arvo ei ole 0"); // Viimeinen rivi ohjelmassa Testaaja.onkoValmis();
Onnistunut toteutus tuottaa seuraavan tulosteen:
--[ Testaaja ]--------------------------------- Ei virheitä, tehtävä valmis!
Toteuta luokka Rautatiesilta
, joka periytyy luokasta Silta
.
Rautatiesilta rs = new Rautatiesilta(100); if (rs.getPituus() != 100 ) Testaaja.virhe("Pituus ei ole 100"); if (rs.getArvo() != 0) Testaaja.virhe("Laskuri ei palauta 0"); Testaaja.vaadiPerinta(rs, Silta.class); Testaaja.tarkistaAttribuutit(Rautatiesilta.class);
Toteuta luokka Juna
, joka tietää vaunujen määränsä kokonaislukuna
Juna pitkaJuna = new Juna(28); Juna lyhytJuna = new Juna(10); if (pitkaJuna.getVaunut() != 28) Testaaja.virhe("Pitkän junan vaunujen lukumäärä ei ole 28"); if (lyhytJuna.getVaunut() != 10) Testaaja.virhe("Lyhyen junan vaunujen lukumäärä ei ole 10"); Testaaja.tarkistaAttribuutit(Juna.class);
Kun juna ylittää sillan, kasvaa sillan laskurin arvo ylittäneen junan vaunujen mukaan.
if (!pitkaJuna.ylita(rs)) Testaaja.virhe("Pitkä juna ei ylita siltaa"); if (!lyhytJuna.ylita(rs)) Testaaja.virhe("Lyhyt juna ei ylitä siltaa"); if (rs.getArvo() != 38 ) Testaaja.virhe("Rautatiesillan ylittäneiden vaunujen määrä on: "+rs.getArvo()+", eikä ole 38, vaikka kaksi junaa (28 ja 10 vaunua) ylittivät sillan");
Toteuta luokka Maantiesilta
, joka periytyy luokasta Silta
.
Maantiesilta ms = new Maantiesilta(50); if (ms.getPituus() != 50) Testaaja.virhe("Pituus ei ole 50"); Testaaja.vaadiPerinta(ms, Silta.class); Testaaja.tarkistaAttribuutit(Maantiesilta.class);
Toteuta luokka Matti
, joka tietää painonsa sukunimen char
-arvon perusteella
Matti mattiP = new Matti('P'); Matti mattiV = new Matti('V'); if (mattiP.getPaino() != 80) Testaaja.virhe("Matti P:n paino ei ole 80"); if (mattiV.getPaino() != 86) Testaaja.virhe("Matti V:n paino ei ole 86"); Testaaja.tarkistaAttribuutit(Matti.class);
Kun Matti ylittää maantiesillan, kasvaa sillan laskurin arvo kasvaa Matin painon mukaan.
if (!mattiP.ylita(ms) ) Testaaja.virhe("Matti P. ei ylitä siltaa!"); if (!mattiV.ylita(ms) ) Testaaja.virhe("Matti V. ei ylitä siltaa!"); if (ms.getArvo() != 166) Testaaja.virhe("Maantiesillan ylittänyt paino on: "+ms.getArvo()+", eikä 166");
Toteuta luokka Auto
, joka ylittäessään siltaa kasvattaa arvoa aina tuhannella.
Auto audi = new Auto(); if (!audi.ylita(ms)) Testaaja.virhe("Audi ei ylitä maantiesiltaa"); if (ms.getArvo() != 1166) Testaaja.virhe("Maantiesillan ylittänyt paino on: "+ms.getArvo()+", eikä 1166");
Tee luokka Pelaaja
, johon voidaan tallettaa pelaajan nimi, joukkue, maalimäärä, syöttömäärä ja plusmiinustieto.
Talleta seuraavat pelaajat ArrayList:iin
pisteporssi.add(new Pelaaja("Nicklas Backstrom", "WAS", 29, 60, 33)); pisteporssi.add(new Pelaaja("Marian Gaborik", "NYR", 37, 39, 8)); pisteporssi.add(new Pelaaja("Henrik Sedin", "VAN", 28, 71, 35)); pisteporssi.add(new Pelaaja("Sidney Crosby", "PIT", 45, 44, 8)); pisteporssi.add(new Pelaaja("Martn St.Louis", "TBL", 27, 60, -4)); pisteporssi.add(new Pelaaja("Steven Stamkos", "TBL", 43, 40, 0)); pisteporssi.add(new Pelaaja("Joe Thorton", "SJS", 19, 66, 16)); pisteporssi.add(new Pelaaja("Alexander Ovechkin", "WSH", 45, 53, 44)); pisteporssi.add(new Pelaaja("Patrick Kane", "NJD", 28, 54, 18)); pisteporssi.add(new Pelaaja("Brad Richards", "DAL", 21, 61, -13));
Tulosta pelaajalistan sisältö. Huomaa, että tulostukseen tulee mukaan myös kokonaispistemäärä eli maalien ja syöttöjen summa:
Nicklas Backstrom WAS 29+60 = 89 33 Marian Gaborik NYR 37+39 = 76 8 Henrik Sedin VAN 28+71 = 99 35 Sidney Crosby PIT 45+44 = 89 8 Martn St.Louis TBL 27+60 = 87 -4 Steven Stamkos TBL 43+40 = 83 0 Joe Thorton SJS 19+66 = 85 16 Alexander Ovechkin WSH 45+53 = 98 44 Patrick Kane NJD 28+54 = 82 18 Brad Richards DAL 21+61 = 82 -13
Lisää luokalle Pelaaja rajapinta Comparable<Pelaaja>
, jonka avulla pelaajat voidaan järjestää kokonaispistemäärän mukaiseen järjestykseen. Järjestä pelaajat Collections-luokan avulla ja tulosta pistepörssi:
NHL pistepörssi 1. Henrik Sedin VAN 28+71 = 99 35 2. Alexander Ovechkin WSH 45+53 = 98 44 3. Nicklas Backstrom WAS 29+60 = 89 33 4. Sidney Crosby PIT 45+44 = 89 8 5. Martn St.Louis TBL 27+60 = 87 -4 6. Joe Thorton SJS 19+66 = 85 16 7. Steven Stamkos TBL 43+40 = 83 0 8. Patrick Kane NJD 28+54 = 82 18 9. Brad Richards DAL 21+61 = 82 -13 10. Marian Gaborik NYR 37+39 = 76 8
Ohjeita tähän tehtävään viime viikon materiaalissa.
Haluamme tulostaa myös maalintekijäpörssin eli pelaajien tiedot maalimäärän mukaan järjestettynä sekä syöttöpörssin ja plusmiinustilaston. NHL:n kotisivu tarjoaa tämänkaltaisen toiminnallisuuden, eli selaimessa näytettävä lista on mahdollista saada järjestettyä halutun kriteerin mukaan.
Edellinen tehtävä määritteli pelaajien suuruusjärjestyksen perustuvan kokonaispistemäärään. Luokalla voi olla vain yksi compareTo-metodi, joten joudumme muunlaisia järjestyksiä saadaksemme turvautumaan muihin keinoihin.
Vaihtoehtoiset järjestämistavat toteutetaan erillisten luokkien avulla. Pelaajien vaihtoehtoisten järjestyksen määräävän luokkien tulee toteuttaa Comparator<Pelaaja>
-rajapinta. Järjestyksen määräävällä luokalla on ainoastaan yksi metodi compareTo(Pelaaja p1, Pelaaja p2)
, jonka tulee palauttaa negatiivinen arvo, jos p1 on järjestyksessä ennen p2:sta, positiivinen arvo jos p2 on järjestyksessä ennen p1:stä ja 0 muuten.
Periaatteena on luoda jokaista järjestämistapaa varten oma vertailuluokka, esim. maalipörssin järjestyksen määrittelevä luokka:
import java.util.Comparator; public class Maali implements Comparator<Pelaaja> { public int compare(Pelaaja p1, Pelaaja p2) { // koodi tänne } }
Järjestäminen tapahtuu edelleen luokan Collections
metodin sort
avulla. Metodi saa nyt toiseksi parametrikseen järjestyksen määräävän luokan olion:
Maali maalintekijat = new Maali(); Collections.sort(pisteporssi, maalintekijat); System.out.println("\nNHL parhaat maalintekijät"); tulosta(pisteporssi);
Järjestyksen määrittelevä olio voidaan luoda suoraan sort-kutsun yhteydessä:
Collections.sort(pisteporssi, new Maali()); System.out.println("\nNHL parhaat maalintekijät"); tulosta(pisteporssi);
Kun sort-metodi saa järjestyksen määrittelevän olion parametrina, se käyttää olion compareTo()
-metodia pelaajia järjestäessään.
Tarkempia ohjeita vertailuluokkien tekemiseen täällä
Tee seuraaviin tilanteisiin sopivat vertailufunktiot ja tulosta tilastot ohjelmassasi:
NHL parhaat maalintekijät 1. Alexander Ovechkin WSH 45+53 = 98 44 2. Sidney Crosby PIT 45+44 = 89 8 3. Steven Stamkos TBL 43+40 = 83 0 4. Marian Gaborik NYR 37+39 = 76 8 5. Nicklas Backstrom WAS 29+60 = 89 33 6. Henrik Sedin VAN 28+71 = 99 35 7. Patrick Kane NJD 28+54 = 82 18 8. Martn St.Louis TBL 27+60 = 87 -4 9. Brad Richards DAL 21+61 = 82 -13 10. Joe Thorton SJS 19+66 = 85 16 NHL eniten syöttöjä 1. Alexander Ovechkin WSH 45+53 = 98 44 2. Sidney Crosby PIT 45+44 = 89 8 3. Steven Stamkos TBL 43+40 = 83 0 4. Marian Gaborik NYR 37+39 = 76 8 5. Nicklas Backstrom WAS 29+60 = 89 33 6. Henrik Sedin VAN 28+71 = 99 35 7. Patrick Kane NJD 28+54 = 82 18 8. Martn St.Louis TBL 27+60 = 87 -4 9. Brad Richards DAL 21+61 = 82 -13 10. Joe Thorton SJS 19+66 = 85 16 NHL plusmiinustilasto 1. Alexander Ovechkin WSH 45+53 = 98 44 2. Henrik Sedin VAN 28+71 = 99 35 3. Nicklas Backstrom WAS 29+60 = 89 33 4. Patrick Kane NJD 28+54 = 82 18 5. Joe Thorton SJS 19+66 = 85 16 6. Sidney Crosby PIT 45+44 = 89 8 7. Marian Gaborik NYR 37+39 = 76 8 8. Steven Stamkos TBL 43+40 = 83 0 9. Martn St.Louis TBL 27+60 = 87 -4 10. Brad Richards DAL 21+61 = 82 -13
Haluamme ohjelmaamme seuraavien pelaajien tiedot:
Henrik Sedin VAN 74 28 71 99 35 Alex Ovetshkin WSH 64 45 53 98 44 Sidney Crosby PIT 73 45 44 89 8 Nicklas Backstrom WSH 74 29 60 89 33 Martin St.Louis TBL 74 27 60 87 -4 Steven Stamkos TBL 74 45 41 86 0 Joe Thornton SJS 74 19 66 85 16 Patrick Kane CHI 73 28 54 82 18 Brad Richards DAL 72 21 61 82 -13 Marian Gaborik NYR 68 39 40 79 10 Patrick Marleau SJS 74 41 35 76 18 Dany Heatley SJS 74 38 37 75 13 Anze Kopitar LAK 73 33 42 75 4 Ilja Kovaltshuk NJD 67 38 37 75 6 Daniel Sedin VAN 56 22 52 74 34 Aleksander Semin WSH 65 35 38 73 29 Zach Parise NJD 72 35 38 73 21 Paul Stastny COL 73 18 55 73 8 Mike Green WSH 69 17 54 71 33 Corey Perry ANA 74 26 44 70 0
Tietojen syöttäminen käsin on hankalaa. Luo tiedosto, johon copypastaat pelaajalistan. Lue tiedosto ohjelmassasi ja luo jokaiselle pelaajalle oma olio. Listalla ensimmäinen luku on pelaajan ottelumäärä. Sitä, eikä toiseksi viimeistä (kokonaispistemäärä) ei oteta mukaan pelaajaolioita luotaessa.
Tiedoston lukeminen kannattaa hoitaa kahden eri metodin avulla. Metodilla next()
voidaan lukea tiedoston seuraava merkkijono joka rajoittuu välilyöntiin, tabulaattoriin tai enteriin. Metodilla nextInt()
voidaan lukea tiedostossa olevat kokonaisluvut.
Tiedoston jokainen rivi on samanlainen: String String String int int int int int
, joten
kutsumalla metodeita next()
ja nextInt()
riviltä on helppo lukea oikeat tiedot. Metodilla hasNext()
voidaan testata pitääkö tiedoston lukemista vielä jatkaa:
Scanner lukija = lukija = new Scanner(new File("pelaajat.txt")); while ( lukija.hasNext() ){ // vieläkö jatketaan String nimi = lukija.next()+" "+lukija.next(); String joukkue = lukija.next(); lukija.nextInt(); // hypätään ottelumäärän yli int maalit = lukija.nextInt(); int syotot = lukija.nextInt(); lukija.nextInt(); // hypätään kokonaispistemäärän yli yli int plusMinus = lukija.nextInt(); pisteporssi.add(new Pelaaja(nimi, joukkue, maalit, syotot, plusMinus)); }
Lue tiedostosta pelaajatiedot ja tulosta pistepörssi, maalipörssi, syöttöpörssi ja plusmiinustilasto.
Olemme viime viikkoina toteuttaneet olutmuistiot, jotka syötetään käsin. Lisätään tässä tehtävässä olutmuistioihin toiminnallisuutta, joka mahdollistaa niiden lukemisen tiedostosta.
Olutmuistiot on tallennettu seuraavassa muodossa tiedostoon. Voit copy-pasteta seuraavan tekstin omaan tiedostoon.
Matti L Stone Brewery: Arrogant Bastard Ale Ballast Point: Panzer Imperial Pils Matti P Celebration Ale Matti V Franzis Kristal Weissbier Paderborner Pilsener
Toteuta seuraavat tehtävät lisänä ensimmäisellä viikolla olleeseen olutmuistioon. Kun olutmuistiot on luettu, voidaan uusia vielä luoda.
Luo olutmuistioiden omistajat tiedostoa lukemalla. Ylläolevalla tiedostolla luodaan kolme olutmuistiota, joiden omistajat ovat "Matti L", "Matti P" ja "Matti V". Olutmuistioiden tulostuksen pitäisi näyttää tässä vaiheessa seuraavalta:
Alkuperäiset muistiot: Olutmuistion omistaja: Matti L Oluita yhteensa 0 kpl Olutmuistion omistaja: Matti P Oluita yhteensa 0 kpl Olutmuistion omistaja: Matti V Oluita yhteensa 0 kpl Lisätään muistioita Anna muistion omistaja: ...
Muokkaa edellistä toteutusta siten, että olutmuistioihin luetaan myös juodut oluet. Tulostuksen tulee olla muutoksen jälkeen seuraavanlainen:
Alkuperäiset muistiot: Olutmuistion omistaja: Matti L Oluita yhteensa 2 kpl Stone Brewery: Arrogant Bastard Ale Ballast Point: Panzer Imperial Pils Olutmuistion omistaja: Matti P Oluita yhteensa 1 kpl Celebration Ale Olutmuistion omistaja: Matti V Oluita yhteensa 2 kpl Franzis Kristal Weissbier Paderborner Pilsener Lisätään muistioita Anna muistion omistaja: ...
Toteutaan oma yksinkertainen String
-luokka: MunString
100
char
-taulukkoon.toString()
-metodin palauttamaa Stringiä siten, että se ei ole MAXPITUUS pitkä (vaan ylempänä mainitun pituuden verran). Tutustu String
-luokan substring
-metodiin.lisaa()
-metodilla yritetään kasvattaa merkkijono pidemmäksi kuin MAXPITUUS, metodi ei tee mitään (katso testiohjelma).Vinkki toString()
-metodiin: Stringin voi luoda char-taulukosta new String(chartaulukko)
.
Testiohjelma:
MunString tervehdys = new MunString("Kokeillaan MunStringia"); MunString lisays = new MunString(", lisäkokeilu."); MunString kymmenen = new MunString("0123456789"); System.out.println("tervehdys: " + tervehdys); System.out.println(" pituus: " + tervehdys.length()); System.out.println(" kolmas: " + tervehdys.charAt(2)); tervehdys.lisaa(lisays); System.out.println("tervehdys: " + tervehdys); tervehdys.lisaa(kymmenen); tervehdys.lisaa(kymmenen); tervehdys.lisaa(kymmenen); tervehdys.lisaa(kymmenen); tervehdys.lisaa(kymmenen); tervehdys.lisaa(kymmenen); tervehdys.lisaa(kymmenen); tervehdys.lisaa(kymmenen); tervehdys.lisaa(kymmenen); tervehdys.lisaa(kymmenen); tervehdys.lisaa(kymmenen); tervehdys.lisaa(kymmenen); tervehdys.lisaa(kymmenen); System.out.println("tervehdys: " + tervehdys); System.out.println(" pituus: " + tervehdys.length());
Tulostus
tervehdys: Kokeillaan MunStringia pituus: 22 kolmas: k tervehdys: Kokeillaan MunStringia, lisäkokeilu. tervehdys: Kokeillaan MunStringia, lisäkokeilu.012345678901234567890123456789012345678901234567890123456789 pituus: 96
Muokataan olemassaolevaa toteutustamme. Jos et ole tehnyt Sokkelo-tehtäviä tähän mennessä, tutustu viimeisen viikon mallivastauksiin!
Luokalla Esine
on sijainti, ja se toteuttaa viime viikolla nähdyn Sijaitseva-rajapinnan. Muuta viime viikon Sijaitseva-rajapintaa siten, että se toteuttaa tällä viikolla nähdyt get- ja set-nimeämissäännöt. Toteuta luokka Esine
. Peri myös luokka Aarre
luokasta Esine
.
Luokka Hahmo
perii luokan Esine
, ja lisää sinne liikkumistoiminnallisuuden. Luokalla Hahmo
on siis metodi liiku()
, jolla hahmoa voi liikuttaa. Toteuta luokka Hahmo
. Peri luokat Morko
ja Pelaaja
luokasta Hahmo
.
Mörkömme on tähän asti vain kävellyt sokkelossa satunnaisesti. Muutetaan mörön liikkumistoimintoa siten, että se pyrkii pelaajaa kohti. Mörkö tietää pelaajan sijainnin Sokkelo
-olion avulla.
Muuta mörön liiku()
-metodia siten, että se pyrkii aina pelaajaa kohti. Jos mörön ja pelaajan etäisyys toisistaan on suurempi y-akselilla kuin x-akselilla, pyri liikkumaan y-akselilla, muulloin x-akselilla. Alla olevissa tilanteissa ensimmäisessä mörön kannattaa liikkua vasemmalle, kun taas toisessa ylös.
O M
O M
Kannattaa tutkia haluttua liikkumissuuntaa mörön ja pelaajan x- ja y-koordinaattien erotuksena.
Lisätään kartalle vielä portaali, mihin kävelemällä pelaaja päätyy toisen portaalin sijaintiin. Portaali merkitään numerolla 4 kartalle.
int[][] taulukko = { {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 2, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 4, 1, 0, 1, 0, 0, 1, 1}, {1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1}, {1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1}, {1, 0, 1, 3, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1}, {1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, -1}, {1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1}, {1, 4, 1, 0, 0, 99, 1, 0, 1, 3, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} };
Toteuta portaali-toiminnallisuus. Jos portaaleja on enemmän kuin kaksi, portaali mihin päädytään arvotaan portaalien joukosta.