ohjelmointitekniikka
Transcription
ohjelmointitekniikka
C# - kieli • 1. ohjelman selitystä – Muutamien ohjelman yksityiskohtien läpikäyntiä class MainClass { public static void Main(string[] args) { Console.WriteLine("Hei maailma!"); } } – jokainen C#-ohjelma on aina luokka (class) – luokassa voidaan määritellä metodeita • jokaisessa itsenäisessä C#-ohjelmassa on main-metodi • main-metodi on julkinen (public), luokan oma (static) ja arvoa palauttamaton (void) • main-metodilla on merkkijonotyyppinen (String) parametri args – lause ”Console.WriteLine...” tulostaa kuvaruudulle tekstin ”Hei maailma!” Ohjelman muoto • Ohjelman luettavuus – Kirjoitetaan jokainen lause omalle riville • Useampiakin voit kirjoittaa mutta se haittaa luettavuutta – Käytä sisennyksiä – Kirjoita kommentteja • Kommentit – kommentti on vapaamuotoinen selitysteksti, joka ei vaikuta ohjelman suorittamiseen – ilmaus ”/*” aloittaa kommentin ja ”*/” lopettaa kommentin – ilmaus ”//” kertoo, että tokarivi on kommenttia // Tämä on kommenttirivi /* Tämä on kommenttitekstiä, ja se jatkuu usealle riville. */ 1 Kommentit • Jokaisen ohjelman ekaun kannattaa kirjoittaa kommentit • Esim. /* * Ohjelma : Tervehdys * tekijä: Juha Stenfors * valmis: 28.8.2005 * muutos: 10.9.2005 / Tulostustekstit muutettu * muutos: 18.9.2005 / lisätty kommentteja */ • Tee jokaiselle sellaiselle riville kommentti, joita haluat selventää • Auttaa jatkossa, kun tutkit ohjelmaa ja sen logiikkaa Tietotyypit • (tieto)tyyppi liittyy moneen asiaan ohjelmointikielessä: – – – – muuttujalla on aina tyyppi arvolla on aina tyyppi parametrilla on aina tyyppi (käsitellään myöhemmin) metodin paluuarvolla on aina tyyppi (käsitellään myöhemmin) • C#-kieli on ns. vahvasti tyypitetty kieli – sijoitusoperaatioissa ja vertailuissa vaaditaan aina yhteensopivuus arvojen kesken 2 Tietotyypit Tietotyyppi Tunnus Muisti .Net tyyppi Arvoalue lyhyt kokonaisluku kokonaisluku pitkä kokonaisluku yksinkert. tark. liukuluku kaksoistarkkuden liukuluku pitkä liukuluku totuusarvo tavu merkki short int long float double decimal bool byte char 2 tavua 4 tavua 8 tavua 4 tavua 8 tavua 16 tavua 1 tavu 1 tavu 8 tavua Int16 Int32 Int64 Single Double Decimal Boolean Byte Char -32768 – 32767 -2147483648 – 2147483647 -9223372036 854 775 808 - 9223372036 854 775 807 -3.4028235E38 – 3.402835E38 -1.79769313486231E308 - 1.79769313486231E3080 enintään +/- 79228 * 10 ^24 True tai False 0 - 255 Mikä tahansa Unicode – symboli välillä 0 – 65535 * Huom! Desimaalierotin ohjelmassa on piste! Tietotyypit • Merkki (char) – jokaista merkkiä vastaa tietty numeroarvo – C#:ssa merkit on koodattu ns. Unicode-merkkijärjestelmällä • sisältää maailman useimpien kirjoitusjärjestelmien kirjain- ja numeromerkit • vakioarvot esitetään heittomerkkien sisällä: ’c’, ’C’, ’6’, ’;’ – erikoismerkkejä: ’\t’ tabulaattori ’\\’ kenoviiva ’\n’ rivinvaihto ’\”’ lainausmerkki ’\’’ heittomerkki 3 Tietotyypit • Merkkijono (string) – – – – merkkijono alkaa ja tokau lainausmerkkeihin saa sisältää mitä tahansa merkkejä voidaan yhdistellä katenaatio-operaattorin (+) avulla esimerkkejä: ”Auto” ”Auto on kulkuväline” ”Auto\n on\n kulkuväline” ( \n = rivinvaihtomerkki ) ”Auto” + ” ” + ”on” + ” ” + ”kulkuväline” Tietotyypit • Totuusarvo (boolean) – mahdolliset arvot: true (= tosi) ja false (= epätosi) – loogisen lausekkeen arvo on aina totuusarvo – esimerkkejä: true, false, x > 0, (x ==5) && (y != 3) 4 Muuttujat • muuttuja määritellään ennen käyttöä muodossa tyyppi muuttujan_nimi; • muuttujan nimi alkaa aina kirjaimella • pienet ja isot kirjaimet ymmärretään eri merkeiksi: esim. Kissa ja kissa ovat eri nimiä • esimerkkejä: int lkm, kpl; // lkm ja kpl ovat kokonaislukutyyppisiä double pinta_ala; // pinta_ala on desimaalilukutyyppinen boolean totuus; // totuus on totuusarvotyyppinen string nimi; // nimi on merkkijonoarvoinen • useasti on tapana nimeämissä käyttää muuttujan nimessä 1. kirjaimena tyypin ensimmäistä kirjainta tai tyypin kolmea ensimmäistä kirjainta • int iLuku; • string sNimi; Muuttujat • nimeämisessä suositaan seuraavaa tapaa: – – – – – nimen 1. kirjain on pieni jokainen seuraava sana nimessä alkaa isolla kirjaimella kaikki muut kirjaimet ovat pieniä skandeja (ääkkösiä) ei pitäisi käyttää nimi ei saa olla C#-kielen varattu sana • esimerkkejä muuttujanimistä nelionPintaAla autonRenkaanIlmanPaine keski_ika iYhteensa sKatuOsoite 5 Sijoituslauseita • sijoitusoperaattori on yhtäsuuruusmerkki (=) muuttuja = lauseke; • huom. älä sekoita sijoitusoperaattoria yhtäsuuruusoperaattoriin, joka on kaksi yhtäsuuruusmerkkiä (==) • muuttujan ja lausekkeen tulee olla sijoitusyhteensopivia (eli lähes aina samaa tyyppiä) • esimerkkejä: int luku; double pinta_ala; boolean totuus; string postiosoite; luku = 1237; pinta_ala = 9887.120; totuus = true; postiosoite = ”Tiedepuisto 3”; Sijoituslauseita • muuttujille voidaan antaa ekaarvo jo määrittelyssä: int luku = 1237; double pinta_ala = 9887.120; boolean totuus = true; string postiosoite = ”Tiedepuisto 3”; • algoritmeissa muuttujan uusi arvo lasketaan usein vanhasta arvosta luku = luku + 10; pinta_ala = pinta_ala - 3; – näissä on mahdollista käyttää erityisiä sijoitusoperaattoreita luku += 10; pinta_ala -= 3; – usein muuttujan arvoa kasvatetaan/vähennetään yhdellä luku = luku + 1; on sama kuin ++luku; luku++; pinta_ala = pinta_ala - 1; on sama kuin pinta_ala--; 6 Laskutoimitukset • • • • • • yhteenlasku (+) vähennyslasku (-) jakolasku (/) kertolasku (*) jäännösjako (%) jakolaskussa jaettavan ja jakajan ollessa kokonaisluku tuloskin on aina kokonaisluku (= ns. kokonaisjako) • jäännösjako on kokonaislukujen jakolaskun jakojäännös • esimerkki int luku = 5, kpl = 100; double leveys = 2.2, korkeus = 5; kpl = luku / 2; luku = 22 % 3; leveys = korkeus / 2; // arvo on 2 (eikä 2.5)! // arvo on 1 // arvo on 2.5 Katenointi • katenointi tarkoittaa merkkijonojen liittämistä toisiinsa • katenointioperaattori on +-merkki • jos lauseke on muotoa merkkijono + numeerinen arvo, yhteenlasku tulkitaan katenaatioksi • esimerkki string eka = ”luokka”, toka = ”huone”, yht; yht yht yht yht = = = = eka + toka; // arvo on ”luokkahuone” toka + eka; // arvo on ”huoneluokka” eka + ” ” + toka; // arvo on ”huone luokka” toka + eka + ”an ” + toka; // arvo on ”huoneluokkaan huone” yht = toka + 210; // arvo on ”huone210” 7 Kirjoittaminen ja lukeminen • näytölle tulostetaan valmiiksi määritellyn nimiavaruuden System avulla (using System;) Console.WriteLine(”Hei maailma!”); // tulostaa tekstin Console.Write(”Hei maailma!”); // tulostaa tekstin ja rivinvaihdon • tulostettava on aina vain yksi arvo – jos halutaan tulostaa esim. tekstiä ja lukuarvoja, niistä on tehtävä yksi merkkijono string sNimi = ”Juha”; Console.WriteLine(”Moi ” + sNimi + ”!”); – tämä tulostaisi (näytölle): Moi Juha! Kirjoittaminen ja lukeminen Console.WriteLine(”Jos haluat tulostaa \”lainausmerkit\”!”); Console.WriteLine(”Tyhjiä rivejä kaksi:\n\n”); Console.WriteLine(”\tYksi tabulointi”); Console.WriteLine(”\t\t\tTabuloitu kolme kertaa”); Console.WriteLine(”C:\\>”); Console.WriteLine(”\\\\alfa\\yleiset”); Jos haluat tulostaa ”lainausmerkit”! Tyhjiä rivejä kaksi: Yksi tabulointi Tabuloitu kolme kertaa C:\> \\alfa\yleiset 8 Loogiset lausekkeet • lähtökohtana bool - tietotyyppi • arvot true (tosi) ja false (epätosi) • looginen lauseke (eli totuusarvoinen lauseke) muodostuu – ehtolausekkeista ja niitä yhdistävistä loogisista operaattoreista • ehtolausekkeen yleinen muoto: arvo vertailuoperaattori arvo muuttuja, > >= muuttuja, vakio, < <= vakio, lauseke == != lauseke Loogiset lausekkeet • esimerkkejä: luku >= 0 iMaara == 100 arvo < (luku * 2.4) – älä sekoita yhtäsuuruusoperaattoria (==) ja sijoitusoperaattoria (=): luku == 10 luku = 10 // ”onko luku:n arvo 10?” // ”luku saa arvokseen 10” • merkkijonoja voit verrata samalla tavalla kuten lukuja sNimi == ”Juha” // ”onko sNimi:n arvo Juha?” • ehtolausekkeita voidaan yhdistellä loogisin operaattorein: && ja (and) || tai (or) ^ poissulkeva tai (xor) ! ei (not) 9 Loogiset lausekkeet • esimerkki int iLuku = 2; double dPi = 3.14; bool b1, b2, b3; b1 = (i == 2) && (dPi > 10.0); b2 = (i == 2) && (dPi < 10.0); // b1 saa arvon false // b2 saa arvon true b1 = (i == 2) || (dPi > 10.0); b2 = (i != 2) || (dPi > 10.0); // b1 saa arvon true // b2 saa arvon false b3 = !b1 || !!b2; // b3 saa arvon false Tehtävä Alustetaan seuraavat muuttujat: int a, b, c; short x, y, z; Kirjoita looginen lauseke seuraaviin tapauksiin: 1. a on parillinen 2. b on nollaa suurempi, ja b on pienempi kuin 120 3. b on suurempi kuin c, ja b on pienempi kuin a 4. -11.2 < x < -2.42 5. joko a on 4 ja b on negatiivinen tai y on suurempi kuin z:n ja x:n erotus 6. z < -1.7 tai z > 23.1, c:n ja a:n summa on parillinen ja b ei ole 543 7. joko a on 7 tai b on c, mutta eivät molemmat 8. joko x on positiivinen tai y on negatiivinen, mutta eivät molemmat 10 Ratkaisu 1. 2. 3. 4. 5. 6. 7. 8. a % 2 == 0 (b > 0) && (b < 120) (b > c) && (b < a) (x >-11.2) && (x < -2.42) (a == 4) && (b < 0) || (y > z – x) ((z < -1.7) || (z > 23.1)) && ((a + c) % 2 == 0) && (b != 543) (a == 7) ^ (b == c) (x > 0) ^ (y < 0) if-lause • ehdollisella lauseella eli if-lauseella on kaksi muotoa: if (ehtolauseke) lause; jos ehto on tosi, niin lause suoritetaan eli ehtolauseke ehdollistaa lauseen suorituksen if (ehtolauseke) lause1; else lause2; jos ehto on tosi, niin suoritetaan lause1, muuten suoritetaan lause2 eli lauseet lause1 ja lause2 ovat vaihtoehtoisia 11 if-lause double dLuku1, dLuku2; Console.Write(”Anna luku1: ”); dLuku1 = Convert.ToDouble(Console.ReadLine()); Console.Write(”Anna luku2: ”); dLuku2 = Convert.ToDouble(Console.ReadLine()); if (dLuku1 < dLuku2){ Console.WriteLine(”Luku1 on pienempi.”); } else { Console.WriteLine(”Luku2 on suurempi tai yhtäsuuri kuin luku1.”); } if-lause • if-lauseessa voidaan ehdollistaa/vaihtoehtoistaa vain yksittäisiä lauseita – jos valittava vaihtoehto muodostuu useammasta kuin yhdestä lauseesta tulee käyttää koottua lausetta (= aaltosulkuparin sisällä olevat lauseet) – kootun lauseen perässä EI ole koskaan puolipistettä! if (ehtolauseke) { lause; ... lause; } if (ehtolauseke) { lause; ... lause; } else { lause; ... lause; } – huom. kootun lauseen sisällä määriteltyä muuttujaa ei voi käyttää kootun lauseen ulkopuolella 12 switch-lause • valintalausetta eli switch-lausetta käytetään silloin kun valintavaihtoehtoja on useita • valintalause on muotoa: switch (lauseke) { case vakio1: lause1; break; case vakio2: case vakio3: lause2; lause3; break; default: lause4; break; } switch-lause int iKK, iPv; Console.Write(”Anna kuukauden numero: ”); iKK = Convert.ToInt32(Console.ReadLine()); switch (iKK) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: iPv = 31; break; case 2: iPv = 28; break; case 4: case 6: case 9: case 11: iPv = 30; break; default: iPv = 0; } Console.WriteLine(”Kuukaudessa ” + iKK + ” on ” + iPv + ” päivää.”); 13 while-lause • while-lause on ns. alkuehtoinen toistolause – toistokertojen määrä ei tarvitse olla etukäteen tiedossa – voidaan käyttää myös lukumääräiselle toistolle (laskurimuuttujan avulla) • while-lauseen muoto: while (ehto) { lause; ... lause; } Ehto on totuusarvoinen lauseke ja sen arvo tarkastetaan aina ennen toistokerran suorittamista. Kun ehto saa arvon epätosi, siirrytään whilelausetta seuraavaan lauseeseen. (Koottua) lausetta toistetaan niin kauan, kun ehto on tosi. while-lause int iLuku, iSumma; Console.WriteLine(”Yhteenlaskuohjelma, negatiivinen luku lopettaa.”); iLuku = Convert.ToInt32(Console.ReadLine()); while (iLuku >= 0) { iSumma = iSumma + iLuku; Console.WriteLine(”Summa nyt: ” + iSumma); iLuku = Convert.ToInt32(Console.ReadLine()); } Console.WriteLine(”Loppu!”); 14 Tehtävä • Ohjelman tulee tulostaa luvut 1, 2, 3 ja 4. Täytä puuttuvat kohdat: int iLaskuri ; iLaskuri = ______; while (iLaskuri _____ 4 ) { Console.WriteLine(iLaskuri); iLaskuri = iLaskuri + _____; } Ratkaisu • Ohjelman tulee tulostaa luvut 1, 2, 3 ja 4. Täytä puuttuvat kohdat: int iLaskuri ; iLaskuri = 1; while (iLaskuri <= 4 ) { Console.WriteLine(iLaskuri); iLaskuri = iLaskuri + 1; } 15 Tehtävä • Ohjelman tulee tulostaa luvut 10 Î -10. Täytä puuttuvat kohdat: int iLaskuri ; iLaskuri = ______; while (iLaskuri _____ ) { Console.WriteLine(iLaskuri); iLaskuri = iLaskuri _____; } Ratkaisu • Ohjelman tulee tulostaa luvut -10 Î 10. Täytä puuttuvat kohdat: int iLaskuri ; iLaskuri = 10; while (iLaskuri >= -10) { Console.WriteLine(iLaskuri); iLaskuri = iLaskuri - 1; } 16 Tehtävä • Mitä ao. koodi tekee? double dLuku1 = 1, dLuku2 = 0, dLuku3 = 0; while (dLuku1 != 0) { Console.WriteLine("Anna luku: "); dLuku1 = Convert.ToDouble(Console.ReadLine()); if (dLuku1 != 0) { dLuku2 = dLuku2 + 1; dLuku3 = dLuku3 + dLuku1; } } Console.WriteLine(dLuku3 / dLuku2); Ratkaisu • Ohjelma siis kysyy käyttäjältä lukuja, niin kauan kuin ne ovat erisuuria kuin 0. Jos luku ei ole nolla lisätään se muuttujaan dLuku3 ja samalla lisätään yhdellä muuttujan arvoa dLuku2. Lopuksi jaetaan dLuku3 dLuku2:lla eli saadaan keskiarvo syötetyistä luvuista ja tulostetaan se. 17 Tehtävä • Tee ohjelma, joka pyytää käyttäjältä alku- ja loppuarvon sekä tulostaa kaikki kokonaisluvut näiden arvojen väliltä. • Käytä toteutukseen while-lausetta. • Kirjoita paperille vastaus ja käytä mahdollisimman eksaktia C# syntaksia. Ratkaisu int iAlku, iLoppu; Console.WriteLine("Anna alkuarvo: "); iAlku = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Anna loppuarvo: "); iLoppu = Convert.ToInt32(Console.ReadLine()); while (iAlku <= iLoppu) { Console.WriteLine(iAlku); iAlku = iAlku + 1; } 18 do-while -lause • do-while –lause on ns. loppuehtoinen toistolause – toistokertojen määrä ei ole etukäteen tiedossa • do-while -lauseen muoto: do { lause; ... lause; } while(ehto); (Koottua) lausetta toistetaan niin kauan, kun ehto on tosi. Huomaa puolipiste! Ehto on totuusarvoinen lauseke ja sen arvo tarkastetaan aina toistokerran suorittamisen jälkeen. Kun ehto saa arvon epätosi, siirrytään while-lausetta seuraavaan lauseeseen. do-while -lause int iAlku, iLoppu; Console.WriteLine("Anna alkuarvo: "); iAlku = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Anna loppuarvo: "); iLoppu = Convert.ToInt32(Console.ReadLine()); do { Console.WriteLine(iAlku); iAlku = iAlku + 1; } while (iAlku <= iLoppu); 19 Tehtävä : Mitä tulostaa ao. koodi ( syöte: 2 ja 5) int iAlku, iLoppu; Console.Write("Anna alkuarvo: "); iAlku = Convert.ToInt32(Console.ReadLine()); Console.Write("Anna loppuarvo: "); iLoppu = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("while - rakenteen avulla "); while (iAlku <= iLoppu) { Console.WriteLine(iAlku); iAlku = iAlku + 1; } Console.WriteLine("vielä do while - rakenteen avulla "); do { Console.WriteLine(iAlku); iAlku = iAlku + 1; } while (iAlku <= iLoppu); Console.WriteLine(""); Ratkaisu Miksi näin? 20 for-lause • for-lause on ns. lukumääräinen toistolause – toistokertojen määrä on etukäteen tiedossa • for-lauseen muoto: for (alkuasetus; ehto; eteneminen) { lause; ... lause; } Alkuasetus suoritetaan yhden kerran ennen toistokertojen alkamista. Alkuasetusta käytetään toistokertojen lukumäärää ylläpitävän laskurimuuttujan (eli ns. indeksimuuttujan) määrittelyyn. Ehto on totuusarvoinen lauseke ja sen arvo tarkastetaan aina ennen toistokerran suorittamista. Eteneminen on lause, joka suoritetaan jokaisen toistokerran jälkeen. Etenemistä hallitaan laskurimuuttujan arvon muuttamisella. for – lause; esimerkki int iLkm; Console.WriteLine(”Montako tähteä haluat: ”); iLkm = Convert.ToInt32(Console.ReadLine()); for (int i = 0; i < iLkm; i=i+1) { Console.Write(”*”); } 21 for – lause; harjoitus • Miten muuttaisit edellistä tehtävää, jotta saisit seuraavanlaisen lopputuloksen? for – lause; ratkaisu int iLkm, iRivit, i, x; Console.Write("Montako tähteä riville haluat: "); iLkm = Convert.ToInt32(Console.ReadLine()); Console.Write("Montako riviä tähtiä haluat: "); iRivit = Convert.ToInt32(Console.ReadLine()); Console.WriteLine(""); for (x = 0; x < iRivit; x = x+1){ for (i = 0; i < iLkm; i=i+1) { Console.Write("* "); } Console.WriteLine(""); } Console.WriteLine(""); 22 for – lause; tehtävä • Tee ohjelma, joka pyytää käyttäjältä alku- ja loppuarvon sekä tulostaa kaikki kokonaisluvut näiden arvojen väliltä. Tee ohjelmasta sellainen, että se toimii suuremmasta luvusta pienempään eli siis tulostaa esim . numerot alkuarvosta 6 Î 0. • Käytä toteutukseen for-lausetta. for – lause; ratkaisu int iAlku, iLoppu, i; Console.Write("Anna alku: "); iAlku = Convert.ToInt32(Console.ReadLine()); Console.Write("Anna loppu: "); iLoppu = Convert.ToInt32(Console.ReadLine()); for (i = iAlku ; i >= iLoppu ; i = i - 1) { Console.WriteLine(i); } 23 Taulukko • jos tarvitaan n kappaletta keskenään samantyyppisiä muuttujia, ne voidaan koota taulukoksi • esimerkki: pyydetään käyttäjältä 8 kokonaislukua – ensin ilman taulukkoa: int iLuku1, iLuku2, iLuku3, iLuku4, iLuku5, iLuku6, iLuku7, iLuku8; Console.Write(”Anna 1. luku:”); iLuku1 = Convert.ToInt32(Console.ReadLine()); Console.Write(”Anna 2. luku:”); iLuku2 = Convert.ToInt32(Console.ReadLine()); Console.Write(”Anna 3. luku:”); iLuku3 = Convert.ToInt32(Console.ReadLine()); ... Console.Write(”Anna 7. luku:”); iLuku7 = Convert.ToInt32(Console.ReadLine()); Console.Write(”Anna 8. luku:”); iLuku8 = Convert.ToInt32(Console.ReadLine()); Taulukko –ja sitten sama taulukon avulla int i; int[] iLuku = new int[8]; for (i=0; i<8; i=i+1) { Console.Write(”Anna ” + (i+1) + ”. luku:”); iLuku[i] = Convert.ToInt32(Console.ReadLine()); } • taulukko koostuu keskenään samantyyppisistä (muuttujatyyppejä) alkioista 100 23 123 265 2 34 554 3 alkio 24 Taulukko • taulukolla on nimi • taulukon alkioihin viitataan nimen ja alkion järjestysnumeron (eli indeksin) avulla –indeksointi alkaa aina nollasta! Taulukko: iLuku indeksi 100 23 123 265 2 34 554 3 0 1 2 3 4 5 6 7 iLuku[0] iLuku[1] iLuku[2] iLuku[3] iLuku[4] iLuku[5] iLuku[6] iLuku[7] – alkioita käytetään kuten tavallisia muuttujia iLuku[2] = 12; iLuku[3] = iLuku[3] + 2; iLuku[4] = iLuku[1] + iLuku[2] + iLuku[3]; Taulukko • taulukko on nimi on muotoa: tietotyyppi[] – esim. kokonaislukutaulukko int[], jonka alkioiden arvoina voi olla inttyyppisiä arvoja • taulukkotyyppisen muuttujan tietotyyppinä on taulukko • uusi taulukko luodaan siis tyyliin tietotyyppi[n], jossa n kertoo alkioiden lukumäärän – esim. 8-alkioinen kokonaislukutaulukko luodaan Î int[8] • taulukkomuuttujan määrittely tietotyyppi[] nimi = new tietotyyppi[n]; int[] luku = new int[8]; 25 Taulukko int[] iLuku = new int[8]; int i; // sijoitetaan luvut taulukoon for (i=0; i<8; i = i + 1) { iLuku[i] = i; } // tulostetaan syötetyt luvut for (i=0; i<8; i = i + 1) { Console.WriteLine(”Alkiossa ” + i + ”:” + iLuku[i]); } • 1. tenttiin tuleva aineisto päättyy tähän ! 26 Olio-ohjelmointi • olioperustaisuus on eräs ohjelmointiparadigma – paradigma = esikuva, malli, kaava – tapa kuvata erilaisten järjestelmien rakennetta ja toimintaa – terminologia on osin vakiintumatonta • miksi? – tarve systematisoida ohjelmistojen rakentamista – vastaa hyvin ihmisen tapaa hahmottaa maailmaa Oliotermistöä • keskeistä olioajattelussa on tiedostaa ero abstraktin ja konkreettisen välillä abstrakti käsite konkreettinen ilmentymä teos Visual C# .NET - kirja auto Nissan Primera –auto parkkipaikalla henkilö opiskelija Matti Möttönen • abstrakti käsite kirjoitetaan C#-kielessä luokaksi ja jokainen sen pohjalta luotu konkreettinen ilmentymä on olio 27 Oliotermistöä • se, mitä abstraktille käsitteelle (luokalle) voidaan tehdä, kirjoitetaan metodeiksi • kaikki tieto, mikä abstraktiin käsitteeseen (luokkaan) liittyy, kirjoitetaan kentiksi • esimerkki: luokka Henkilö kenttä syntymäaika kenttä nimi kenttä ikä metodi ristiminen() metodi tervehdi() metodi vanhene() Oliotermistöä • luokan perusteella luodaan konkreettisia (fyysisiä) olioita Henkilö – luokka kenttä syntymäaika kenttä nimi kenttä ikä metodi ristiminen() metodi tervehdi() metodi vanhene() Luodaan uusi olio Henkilö – olio 12.4.1982 Matti Möttönen 23 v ristiminen() tervehdi() vanhene() Matti Möttönen oliota siis käytetään metodiensa välityksellä. Hän kentät perintönä luokalta ja osaa toimia metodien mukaan. 28 Tehtävä • Suunnittele luokka Auto. • Mitä tietoja autoon liittyy? = kentät • Mitä autolla voidaan tehdä? = metodit Ratkaisu Auto-luokka • kentät: – polttoainesäiliön tilavuus – merkki – malli – hinta – moottoritilavuus • Metodit: – LisääPolttoAinetta(litramäärä) – UusiHinta(uusi hinta) – AvaaOvet() – KäynnistäMoottori() – Aja(suunta) 29 Kenttä • kentät kuvaavat kaikki tiedot, jotka luokkaan liittyvät – luokan pohjalta luodun olion kentillä on oliota kuvaavat arvot • kenttiä käsitellään tyypillisesti vain metodien kautta • kenttä määritellään lähes samoin kuin muuttuja: näkyvyysmääreitä tyyppi nimi; – näkyvyysmääreillä säädellään kentän käytettävyyttä • private = kenttä on käytettävissä vain luokan metodien välityksellä • public = kenttä on käytettävissä luokan ulkopuolelta • esimerkki: private string sSukuNimi; private string sEtuNimi; private int iIka; Metodi • metodilla toteutetaan jokin palvelu, ja sitä ohjataan parametriensa välityksellä • Esimerkki – Onko vuosi 2005 karkausvuosi? – karkausVuosiko(2005) ”Ei” karkausVuosiko(vuosi) 1. 2. 3. Vastaanotetaan parametrina vuosi Selvitetään vuodesta karkausvuosi Palautetaan paluuarvona vastaus 30 Metodi • Metodin toiminta perustuu seuraavaan kaavaan: – lähtötiedot Î toiminta Î vastaus • Esimerkki C# - metodina Î tulo - metodi public int Tulo(int iLuku1, int iLuku2) { int iTulos; iTulos = iLuku1 * iLuku2; return iTulos; } Metodi • metodien avulla luokkaa voidaan käsitellä jollakin tavalla – luokasta luotua oliota käytetään vain metodiensa välityksellä • metodin määrittely (kirjoitetaan johonkin luokkaan elementiksi): [näkyvyysmääreitä] paluuarvon_tyyppi nimi (parametrit) { algoritmi } – näkyvyysmääreillä säädellään metodin käytettävyyttä • private = luokan omassa käytössä oleva metodi • public = muiden luokkien käytössä oleva metodi • static = luokkametodi, jota kutsutaan luokan kautta (kaikille luokan olioille yhteinen) – paluuarvon tyyppi • tietotyyppi, joka kertoo, minkä tyyppisen arvon metodi palauttaa • void = metodi ei palauta lainkaan arvoa 31 Metodi • esimerkki: public void ristiminen(string n) { nimi = n; } public void tervehdi() { Console.WriteLine(”Morjens, olen ” + nimi); } • metodi käynnistetään kutsumalla sitä – metodikutsu muodostuu metodin nimestä sekä mahdollisten parametrien arvoista • esimerkki: ristiminen(”Matti Möttönen”); tervehdi(); Metodi • metodin parametrit – ovat metodin muuttujia, joita käytetään välittämään tietoa metodille sen kutsumisen yhteydessä – parametrit saavat aina (alku)arvonsa metodin kutsumisen yhteydessä – parametrin arvoa ei voi muuttaa itse metodissa – parametrin määrittely on samanlainen kuin muuttujalla: – tietotyyppi nimi • Esimerkki koodista public void Toista(string sText, int iKerta) { int i; for (i=0; i < iKerta; i = i + 1) { Console.WriteLine(sText); } } Koodissa kutsu tapahtuu seuraavasti: Toista(”Hello World”, 2); Î Hello World Hello World 32 Metodi • metodin paluuarvo – osa metodeista on arvon palauttavia – paluuarvon tyyppi kirjoitetaan metodimäärittelyyn ennen metodin nimeä • void tarkoittaa, että paluuarvoa ei ole – jos metodi palauttaa arvon, siinä on oltava return-lause, joka ilmaisee palautettavan arvon • kun return-lause suoritetaan, metodin suoritus päättyy • esimerkki public int KuukaudessaPaivia(int iKk) { switch (iKk) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: return(31); break; case 2: return(28); break; case 4: case 6: case 9: case 11: return(30); break; default: return (0); } } Miten olio luodaan? Miten käytetään? public static void Main(string[] args) { PapuKaija pk = new PapuKaija(); // luodaan pk niminen olio luokasta PapuKaija pk.Ristiminen("Polly"); // kutsutaan metodia Ristiminen pk.Toista("Terve maailma", 2); // kutsutaan metodia Toista } -------------------------------------------------------// HUOM! Tämä eri tiedostoon class PapuKaija { private string sNimi; // määritellään kenttä sNimi , luokalle public void Toista(string sText, int iKerta) // toistetaan haluttua tekstiä haluttu määrä { int i; for (i=0; i < iKerta; i = i + 1) { Console.WriteLine(sText); } } public void Ristiminen(string sText) // tämä metodi asettaa oliolle ( PapuKaijalle) nimen eli siis muuttaa kentän sNimi arvoa { sNimi = sText; } } 33 Miten metodeja käytetään samassa tiedostossa? public static void Main(string[] args) { Ristiminen("Polly"); // kutsutaan metodia Ristiminen Toista("Terve maailma", 2); // kutsutaan metodia Toista } private static string sNimi; // määritellään kenttä sNimi luokalle public static void Toista(string sText, int iKerta) // toistetaan haluttua tekstiä haluttu määrä { int i; for (i=0; i < iKerta; i = i + 1) { Console.WriteLine(sText); } } // tämä metodi asettaa nimen eli siis muuttaa kentän sNimi arvoa public static void Ristiminen(string sText) { sNimi = sText; } // kun metodit samassa tiedostossa kuin Main – metodi pitää avainsana static lisätä näkyvyysmääreen (public) perään sekä metodeilla että kentillä. Metodi • itsenäisessä (= suoritettavassa) C#-ohjelmassa on aina main()-metodi public static void main(string[] args) – C#-ohjelman suoritus tarkoittaa käytännössä mainmetodin suorittamista 34 Metodi • luokassa voi olla myös useita samannimisiä metodeja, joilla on erilaiset parametrit – tätä ilmiötä kutsutaan kuormittamiseksi – esimerkki: public void TulostaNelio(double dSivunPituus) public void TulostaNelio(int iSivunPituus) public void TulostaNelio(int iSivu1, int iSivu2) – esim. metodi Console.WriteLine() on kuormitettu useille erityyppisille parametreille – C# - kääntäjä päättää suoritettavan metodin kutsussa olevien parametriarvojen tyyppien perusteella Olio • • • • olio luodaan luokka-määrityksen pohjalta jokaisella oliolla on omat kentät ja metodit luominen tehdään operaatiolla new luokkaa käytetään samoin kuin tietotyyppiä – muuttujan tyypiksi voidaan asettaa luokka • esimerkki – olkoon määritelty luokka Henkilo – nyt voidaan määritellä tätä tyyppiä oleva muuttuja: Henkilo henk; – muuttujan arvoksi sijoitetaan luokasta luotu (new-operaatio) olio: henk = new Henkilo(); – tämän jälkeen muuttujan arvona olevan olion metodeja voidaan suorittaa: henk.Ristiminen(”Matti Möttönen”); henk.Tervehdi(); 35 Olio Olio Olio A B Ristiminen() Tervehdi() nimi: Polly 2. 3. Ristiminen() Tervehdi() nimi: Pedro Ohjelma … 1. Luo PapuKaija-olio A; 2. A.ristiminen(”Polly”); 3. A.tervehdi(); ... 4. Luo PapuKaija-olio B; 5. B.ristiminen(”Pedro”); 6. B.tervehdi(); .... 4. 1. Luokka Papukaija nimi Ristiminen() Tervehdi() Olio main.cs: class MainClass { public static void main(String[] args) { PapuKaija pkA, pkB; PapuKaija.cs: public class PapuKaija { private string sNimi; public void Ristiminen(string n) { sNimi = n; } public void Tervehdi(string sText, int iKrt ) { int i; for ( i = 0;i < iKrt; i++) { Console.WriteLine(sText + ” olen ” + sNimi ); } } pkA = new PapuKaija(); pkA.Ristiminen(”Polly”); pkA.Tervehdi(”Terve”, 2); pkB = new Henkilo(); pkB.Ristiminen(”Pedro”); pkB.Tervehdi(”Moro”,3); } } } 36 Konstruktori • luokassa voi olla metodi, jota käytetään olion luomiseen • tällaista metodia kutsutaan konstruktoriksi eli rakentajaksi – konstruktorin nimi on aina sama kuin luokan nimi • esimerkiksi luokan Henkilo konstruktori on Henkilo() – konstruktorin määrittelyssä ei käytetä lainkaan paluuarvon tyyppi –määrettä – konstruktori asettaa tyypillisesti kenttien alkuarvoja • kenttien alkuarvoja ei siis tule asettaa kentän määrittelyssä vaan konstruktorissa – luokassa voi olla useita konstruktoreita • keskenään samannimisiä, mutta parametriosat ovat erilaisia (= kuormittaminen) – jos luokassa ei ole määritelty konstruktoria, suoritetaan oliota luotaessa parametriton ns. oletuskonstruktori • käynnistää ns. yliluokan konstruktorin – liittyy olio-ohjelmoinnin käsitteeseen periytyminen, jota emme ole käsitelleet Konstruktori public class Piste { private int x; private int y; public Piste() { x = 0; y = 0; } public Piste(int iArvoX, int iArvoY) { x = iArvoX; y = iArvoY; } public int GetX() { return x; } public int GetY() { return y; } public void Siirry(int iArvoX, int iArvoY) { x = x + iArvoX; y = y + iArvoY; } // kentät // konstruktori // konstruktori // metodi // metodi // metodi } 37 Aksessori • Käsittele luokkien kenttiä ”vain” metodien avulla • metodi, joka asettaa kenttään arvon tai palauttaa paluuarvonaan kentän arvon, kutsutaan aksessorimetodiksi • aksessorimetodit nimetään tyypillisesti Get- ja Set-alkuisiksi • esimerkki public class Henkilo { private int iIka // kenttä public Henkilo() { iIka = 0; } public void SetIka(int iArvo) { iIka = iArvo; } public int GetIka() { return iIka; } // konstruktori // set-aksessorimetodi // get-aksessorimetodi Aksessorit tapa 2. • Toinen tapa käyttää aksessoria public class Henkilo { private int iIka; // kenttä public Henkilo() { // konstruktori iIka = 0; } public int Ika { get { //aksessori return iIka; //palautetaan arvo iIka = value; //asetetaan arvo value - nimisen parametrin avulla } set { } } } 38 Aksessorit; Miten käytetään? • voit käyttää kumpaa tahansa • Aksessori – metodia käytät kuten metodeja yleensä • Tapa 2 eli aksessoria käytät seuraavasti: public static void Main(string[] args) { Henkilo h = new Henkilo(); // olio.aksessori h.Ika++; // voit käyttää aksessoria kuten sekoittaen metodin ja muuttujan Console.WriteLine(h.Ika); // tulostuksessa viittaa suoraan aksessoriin } 39