1 Luokka Murtoluku uudelleen Kirjoitetaan luokka Murtoluku uudelleen niin, että murtolukujen sieventäminen on mahdollista. Sievennettäessä tarvitaan osoittajan ja nimittäjän suurin yhteinen tekijä (syt). Kahden luvun suurin yhteinen tekijä voidaan laskea Euclideen algoritmilla: niin kauan kuin luvut ovat eri suuret, suuremmasta luvusta vähennetään pienempi. Kun luvut ovat yhtäsuuret, saatu luku on alkuperäisten lukujen suurin yhteinen tekijä. Metodi sievenna: public void sievenna() { int luku1, luku2, syt; /* lasketaan osoittajan ja nimittäjän suurin yhteinen tekijä */ luku1 = Math.abs(this.osoittaja); luku2 = Math.abs(this.nimittaja); if (luku1!= 0) { while (luku1!= luku2) if (luku1 > luku2) luku1 = luku1 luku2; else luku2 = luku2 luku1; syt = luku1; /* sievennetään */ this.osoittaja /= syt; this.nimittaja /= syt; Uusi Murtoluku2 luokka ja pääohjelma luokan testaamiseen: public class Murtoluku2 { private int osoittaja; private int nimittaja; public Murtoluku2(int os, int nim) { if (nim == 0) nim = 1; if (nim * os < 0) { // Mahdollinen etumerkki aina osoittajaan this.osoittaja = Math.abs(os); this.nimittaja = Math.abs(nim); else { this.osoittaja = Math.abs(os);
2 this.nimittaja = Math.abs(nim); public int kerroosoittaja() { return this.osoittaja; public int kerronimittaja() { return this.nimittaja; public Murtoluku2 summa(murtoluku2 toinen) { Murtoluku2 uusiluku; int osoittaja1, osoittaja2; int nimittaja1, nimittaja2; osoittaja1 = this.osoittaja; osoittaja2 = toinen.kerroosoittaja(); nimittaja1 = this.nimittaja; nimittaja2 = toinen.kerronimittaja(); /* Lavennetaan luvut samannimisiksi */ osoittaja1 *= nimittaja2; osoittaja2 *= nimittaja1; nimittaja1 *= nimittaja2; /*Luodaan uusi murtoluku summaa varten */ uusiluku = new Murtoluku2(osoittaja1 + osoittaja2, nimittaja1); return uusiluku; public Murtoluku2 tulo(murtoluku2 toinenluku){ Murtoluku2 uusiluku; int uusiosoittaja, uusinimittaja; uusiosoittaja = this.osoittaja * toinenluku.kerroosoittaja(); uusinimittaja = this.nimittaja * toinenluku.kerronimittaja(); uusiluku = new Murtoluku2(uusiOsoittaja, uusinimittaja); return uusiluku; public boolean onkosama(murtoluku2 toinen) { return ((this.osoittaja == toinen.kerroosoittaja()) && (this.nimittaja == toinen.kerronimittaja()));
3 public void sievenna() { int luku1, luku2, syt; /* lasketaan osoittajan ja nimittäjän suurin yhteinen tekijä */ luku1 = Math.abs(this.osoittaja); luku2 = Math.abs(this.nimittaja); if (luku1!= 0) { while (luku1!= luku2) if (luku1 > luku2) luku1 = luku1 luku2; else luku2 = luku2 luku1; syt = luku1; /* sievennetään */ this.osoittaja /= syt; this.nimittaja /= syt; public String tostring() { return this.osoittaja + "/" + this.nimittaja; public class Murtolukutesti3 { public static void main(string[] args) { Murtoluku2 luku1, luku2, summaluku,tuloluku; luku1 = new Murtoluku2(10,20); System.out.println("luku1: " + luku1); luku1.sievenna(); System.out.println("sievennettynä: " + luku1); luku2 = new Murtoluku2( 2, 12); System.out.println("luku2: " + luku2); luku2.sievenna(); System.out.println("sievennettynä: " + luku2); summaluku = luku1.summa(luku2); tuloluku = luku1.tulo(luku2); System.out.println(luku1 + " + " + luku2 + " = " + summaluku); System.out.println(luku1 + " * " + luku2 + " = " + tuloluku); summaluku.sievenna(); System.out.println("summa sievennettynä: " + summaluku); tuloluku.sievenna(); System.out.println("tulo sievennettynä: " + tuloluku);
4 Oliot luokan kenttinä: Piste ja Suorakulmio Luokan kenttien tyyppinä voi olla toinen luokka. Kirjoitetaan luokka Piste tason pisteen esittämiseen. Käytetään sitten Piste luokkaa apuna luokan Suorakulmio määrittelyssä. Suorakulmio esitetään kahden kulmapisteen avulla. Luokan Piste kentät: int xkoord int ykoord Luokan Piste konstruktori ja metodit Piste(int x, int y) int kerrox() int kerroy() void siirrä(int dx, int dy) String tostring() Luokan Suorakulmio kentät Piste kulma1 Piste kulma2 Luokan Suorakulmio konstruktori ja metodit Suorakulmio(Piste piste1, Piste piste2) Piste alakulma() Piste ylakulma() int leveys() int korkeus() int pintaala() String tostring() public class Piste { private int xkoord; private int ykoord; public Piste(int x, int y) { this.xkoord = x; this.ykoord = y; public int kerrox() { return this.xkoord; public int kerroy() { return this.ykoord;
5 public void siirra(int dx, int dy) { this.xkoord = this.xkoord + dx; this.ykoord = this.ykoord + dy; public String tostring() { return "(" + this.xkoord + ", " + this.ykoord + ")"; public class Suorakulmio { private Piste kulma1; private Piste kulma2; public Suorakulmio(Piste p1, Piste p2) { this.kulma1 = p1; this.kulma2 = p2; public Piste alakulma() { if (this.kulma1.kerroy() < this.kulma2.kerroy()) return this.kulma1; else return this.kulma2; public Piste ylakulma() { if (this.kulma1.kerroy() > this.kulma2.kerroy()) return this.kulma1; else return this.kulma2; public int leveys() { int lev; lev = Math.abs(this.kulma1.kerroX() this.kulma2.kerrox()); return lev; public int korkeus() { int kork; kork = Math.abs(this.kulma1.kerroY() this.kulma2.kerroy()); return kork;
6 public int pintaala() { int lev1, kork1, ala; lev1 = this.leveys(); kork1 = this.korkeus(); ala = lev1 * kork1; return ala; public String tostring() { return this.kulma1.tostring() + " " + this.kulma2.tostring(); public class Kulmiotesti { public static void main(string[] args) { Piste piste1, piste2; Suorakulmio kulmio; int ala; piste1 = new Piste(0, 0); piste2 = new Piste(4, 8); System.out.println("piste1: " + piste1 + " piste2: "+ piste2); kulmio = new Suorakulmio(piste1, piste2); System.out.println("kulmio: " + kulmio); ala = kulmio.pintaala(); System.out.println("kulmion pinta ala: " + ala); piste2.siirra( 1, 2); System.out.println("piste2: " + piste2); System.out.println("kulmio: " + kulmio);
7 Kuormittaminen Metodin kutsussa on oltava sama lukumäärä parametreja kuin metodin määrittelyssä. Parametrien on myös oltava oikeaa tyyppiä. Usein samantapaisia asioita halutaan tehdä erityyppisillä parametreilla. Esimerkiksi murtoluku voidaan haluta kertoa toisen murtoluvun sijaan kokonaisluvulla. Java ohjelmissa voidaan määritellä useita metodeja, joilla on sama nimi, mutta erityyppisiä parametreja. Tätä kutsutaan metodin kuormittamiseksi. Metodia kutsuttaessa kääntäjä päättelee todellisten parametrien tyypeistä ja lukumäärästä, mitä samannimisistä metodeista käytetään. Myös konstruktoreita voidaan kuormittaa. Esimerkki: kirjoitetaan luokkaan Murtoluku2 aikaisemman tulo metodin lisäksi toinen, jolle voi antaa parametrina kokonaisluvun: public class Murtoluku2 { //... public Murtoluku2 tulo(murtoluku2 toinenluku){ int uusiosoittaja, uusinimittaja; Murtoluku2 uusiluku; uusiosoittaja = this.osoittaja * toinenluku.kerroosoittaja(); uusinimittaja = this.nimittaja * toinenluku.kerronimittaja(); uusiluku = new Murtoluku2(uusiOsoittaja, uusinimittaja); return uusiluku; public Murtoluku2 tulo(int luku) { return new Murtoluku2(luku * this.osoittaja, this.nimittaja); //... public class Murtolukutesti4 { public static void main(string[] args) { Murtoluku2 luku1, luku2, tulo1, tulo2; int kluku; kluku = 5; luku1 = new Murtoluku2(3, 5); luku2 = new Murtoluku2(8, 5); tulo1 = luku1.tulo(luku2);
8 tulo2 = luku2.tulo(kluku); System.out.println(luku1 + " * " + luku2 + " = " + tulo1); System.out.println(kluku + " * " + luku2 + " = " + tulo2); Toinen esimerkki kuormittamisesta: Ympyra Kirjoitetaan luokka ympyröiden esittämistä varten. Jokaisella ympyrällä on säde ja keskipiste. Kirjoitetaan luokalle useita konstruktoreita, jolloin uusia Ympyra olioita voidaan luoda erilaisilla parametreilla oliota luodessa voidaan antaa keskipisteen koordinaatit joko kahden kokonaisluvun tai valmiin Piste olion avulla. Lisäksi määritellään parametriton konstruktori, joka luo ympyrän, jonka keskipisteenä on origo ja säteenä 0. Luokalla on siis seuraavat konstruktorit: public Ympyra() public Ympyra(Piste keskikohta, double r) public Ympyra(int x, int y, double r) Luokalla on myös metodi siirrakeskipiste, joka on kuormitettu. Uuden keskipisteen koordinaatit voidaan antaa joko Piste olion tai kahden kokonaisluvun avulla: public void siirrakeskipiste(int x, int y) public void siirrakeskipiste(piste uusikeski) public class Ympyra { private Piste keskipiste; private double sade; // konstruktorit public Ympyra() { this.sade = 0.0; this.keskipiste = new Piste(0,0); public Ympyra(Piste keskikohta, double r) { if (r > 0) this.sade = r; else this.sade = 0.0; this.keskipiste = new Piste(keskikohta.kerroX(), keskikohta.kerroy());
9 public Ympyra(int x, int y, double r) { if (r > 0) this.sade = r; else this.sade = 0.0; this.keskipiste = new Piste(x, y); // metodit public double kerrosade() { return this.sade; public void muutasade(double r) { if (r > 0) this.sade = r; public Piste kerrokeskipiste() { return this.keskipiste; public void siirrakeskipiste(int x, int y) { this.keskipiste = new Piste(x, y); public void siirrakeskipiste(piste uusikeski) { this.keskipiste = new Piste(uusiKeski.kerroX(), uusikeski.kerroy()); public double laskepintaala() { double ala; ala = Math.PI * this.sade * this.sade; return ala; public String tostring() { return "Ympyrä: säde " + this.sade + ", keskipiste " + this.keskipiste.tostring();
10 public class Ympyroita { public static void main(string[] args) { Piste piste1; Ympyra isoympyra, pieniympyra; isoympyra = new Ympyra(); System.out.println(isoYmpyra); isoympyra.siirrakeskipiste(5,8); isoympyra.muutasade(16.55); System.out.println(isoYmpyra); System.out.println("Pinta ala: " + isoympyra.laskepintaala()); pieniympyra = new Ympyra( 4, 7, 2.3); System.out.println(pieniYmpyra); piste1 = new Piste( 3, 8); pieniympyra.siirrakeskipiste(piste1); System.out.println(pieniYmpyra);
11 Taulukot Tarkastellaan seuraavaa ongelmaa: Tee ohjelma, joka pyytää käyttäjältä 30 opiskelijan koetulokset (pisteet). Kun käyttäjä on syöttänyt kaikki tulokset, ohjelma tulostaa syötetyt tulokset ja niiden keskiarvon. Koska syötetyt luvut pitää lopuksi tulostaa, pitää niistä jokainen tallentaa johonkin muuttujaan. Jos jokainen tulos tallennetaan omaan muuttujaansa, pitää ohjelmaan kirjoittaa arvon lukeminen ja tallentaminen 30 kertaan. Ratkaisu: käytetään taulukkoa. Taulukko on joukko yhteenkuuluvia alkioita, joilla on kaikilla sama tyyppi. Yksittäiseen taulukon alkioon päästään käsiksi indeksin avulla: taulukon taulu viidenteen alkioon päästään käsiksi merkinnällä taulu[4]. Alkioiden numerointi alkaa 0:sta. Indeksin ei tarvitse olla kokonaislukuvakio, vaan se voi olla mikä tahansa lauseke, jonka arvo on kokonaisluku. Javassa taulukot ovat myös olioita. Taulukkomuuttuja, jonka avulla voidaan viitata int tyyppisiä alkioita sisältävään taulukkoon, määritellään seuraavasti: int[] pisteet; Tämä ei vielä luo itse taulukkoa, vaan se on luotava erikseen: pisteet = new int[30]; luo taulukon, joka voi sisältää 30 kokonaislukua. Koepisteet kysyvä ja tulostava ohjelma seuraavalla sivulla.
12 import java.util.scanner; public class Koepisteet { public static void main(string[] args) { final int MAARA = 30; int[] pisteet; int i, summa = 0; double keskiarvo; Scanner nappaimisto; nappaimisto = new Scanner(System.in); pisteet = new int[maara]; for (i = 0; i < MAARA; i++) { System.out.println("Anna " + (i+1) + ". opiskelijan pisteet"); pisteet[i] = nappaimisto.nextint(); summa = summa + pisteet[i]; System.out.println("Annetut pisteet:"); for (i = 0; i < MAARA; i++) System.out.println(pisteet[i]); keskiarvo = 1.0 * summa / MAARA; System.out.println("Keskiarvo on " + keskiarvo); Ilmaisulla final kerrotaan, että muuttujan MAARA arvoa ei voi muuttaa sen jälkeen, kun sille on kerran annettu arvo. Huomautuksia taulukosta Taulukon indeksit ovat aina int tyyppisiä. Sen sijaan taulukon alkioiden tyyppi voi olla mikä vaan (valitaan taulukkomuuttujan määrittelyssä). Taulukon ensimmäinen indeksi on aina 0 ja viimeinen koko 1, missä koko on taulukko olion luomisessa annettu koko. Taulukon koon saa selville ilmauksella.length. Esimerkiksi taulukon pisteet koon saa selville lausekkeella pisteet.length Taulukon käyttäjä on vastuussa siitä, että indeksinä ei käytetä koskaan arvoa, joka ei ole oikealla välillä. Taulukon alkioilla on oletusalkuarvot. Taulukko olion kokoa ei voi koskaan muuttaa, mutta taulukkomuuttuja voi saada uudeksi arvokseen viitteen erikokoiseen taulukkoon. Taulukkomuuttujan voi alustaa myös seuraavasti, mutta vain muuttujan määrittelyn yhteydessä: int[] luvut = {5, 23, 12, 31, 8; luo viisialkoisen taulukon ja antaa sen alkioille luetellut alkuarvot boolean[] totta = {true, true, false; luo kolmialkioisen taulukon ja antaa alkioille luetellut alkuarvot.