Luokat. Luokat ja olio-ohjelmointi

Koko: px
Aloita esitys sivulta:

Download "Luokat. Luokat ja olio-ohjelmointi"

Transkriptio

1 Luokat 12 Luokat Tässä luvussa laajennamme edellisessä luvussa käsittelemäämme struktuurityyppiä ja siirrymme yhteen C++-ohjelmoijan kaikkein tärkeimmistä välineistä: luokkiin. Käsittelemme myöskin joitakin olio-ohjelmoinnin ideoita ja miten näitä ideoita sovelletaan käytännössä. Käsittelemme seuraavia aiheita: Mitkä ovat olio-ohjelmoinnin perusperiaatteet Miten uusi tietotyyppi luodaan luokaksi ja miten luokan olioita käsitellään Mitä ovat luokan muodostinfunktiot ja miten niitä kirjoitetaan Mikä on oletusmuodostinfunktio ja miten voit tehdä oman oletusmuodostinfunktion Mikä on oletuskopiomuodostin Mikä on ystäväfunktio Mitä oikeuksia ystäväluokalla on Mikä on this-osoitin, miten ja milloin sitä käytetään Luokat ja olio-ohjelmointi Ennen kuin siirrymme kieleen, syntaksiin ja luokkien ohjelmointitekniikoihin, käsittelemme miten jo oppimasi liittyy olio-ohjelmointiin. Perustana olio-ohjelmoinnissa (kutsutaan usein termillä OOP, object oriented programming ) on se, että ohjelmat kirjoitetaan ratkaistavan ongelman muodostavien olioiden avulla, joten ohjelman kehitysprosessiin kuuluu tilanteesta riippuvien tyyppien muodostaminen. Jos kirjoitat ohjelmaa, jonka tarkoituksena on pankkitilisi seuraaminen, sinulla mitä todennäköisemmin tulee olla tietotyyppejä, kuten Tili ja Tilisiirto. Jos ohjelman tarkoitus on analysoida jääkiekkoottelun tuloksia, tyyppeinä olisivat esimerkiksi Pelaaja ja Joukkue. Perustietotyypeillä ei voi mallintaa elävän elämän olioita (tai edes kuvitteellisia) kunnolla. Jääkiekkoilijaa ei voi mallintaa pelkillä tyypeillä double tai int, tai millään muullakaan perustietotyypillä. Tarvitsemme useita erilaisia ja eri tyyppisiä arvoja, jotta voimme kuvata jääkiekkoilijan. 443

2 C++ Ohjelmoijan käsikirja Struktuureilla saimme yhden ratkaisutavan. Olemme nähneet, kuinka voimme struktuurien avulla yhdistää erityyppisiä muuttujia. Struktuurin määrittelyssä voi olla myös funktioita. Edellisessä luvussa määrittelimme struktuurin Laatikko, joka kuvasi laatikkoa. Tämän uuden tyypin avulla pystyimme määrittelemään Laatikko-tyyppisiä muuttujia aivan samaan tapaan kuin perustietotyyppiäkin olevia muuttujia. Pystyimme luomaan ja käsittelemään niin montaa Laatikko-oliota kuin ohjelmassa tarvitsimme. Tämä on jo varsin lähellä elävän elämän oliota. Voimme tietysti käyttää struktuuria myös jääkiekkoilijan tai pankkitilin kohdalla tai minkä tahansa muunkin kohdalla. Struktuurien avulla voimme mallintaa millaisia olioita tahansa ja rakentaa ohjelma niiden ympärille. Eli mihin olio-ohjelmointia sitten oikeastaan tarvitaan? No, kyllä sitä tarvitaan. Struktuuri, sellaisena kuin me olemme sen määritelleet, on suuri askel eteenpäin, mutta olio-ohjelmointiin kuuluu muutakin. Käyttäjän määrittelemien tietotyyppien lisäksi olio-ohjelmointiin kuuluu muitakin tärkeitä lisäideoita kuten kapselointi, tiedon kätkentä, periytyminen ja polymorfismi. Struktuuri ei pysty näitä toteuttamaan. Tarkastellaan seuraavaksi, mitä kukin näistä olio-ohjelmoinnin ideoista pitää sisällään. Näin saamme hyvän perustan yksityiskohtaiselle C++-ohjelmoinnin opiskelulle tässä ja seuraavissa neljässä luvussa. Kapselointi Yleisesti ottaen, tietyn tyyppisen olion määrittelyyn kuuluu joukko erityisiä asioita, joiden avulla oliosta tehdään se, mitä se on. Olio sisältää määritellyn joukon tietoalkioita, jotka kuvaavat olion käyttötarkoituksen riittävän tarkasti. Laatikon kohdalla ne voisivat olla yksinkertaisesti kolme mittaa: pituus, syvyys ja korkeus. Lentokoneen kohdalla niitä olisi huomattavasti enemmän. Olio sisältää myös joukon funktioita, joilla olion tietoalkioita käsitellään. Ne määrittelevät olion operaatiot - eli mitä olion kanssa voi tehdä ja mitä ei. Jokainen tietyntyyppinen olio sisältää nämä samat asiat: joukon tietoalkioita eli jäsenmuuttujia ja joukon operaatioita eli jäsenfunktioita. Tätä tietoalkioiden ja funktioiden yhdistämistä kutsutaan kapseloinniksi. Alla oleva kaavio selventää tätä pankin lainatilin avulla. LainaTili -olio Olio sisältää kaiken, millä sen ominaisuudet ja operaatiot voidaan määritellä. Saldo: mk KorkoPros: 22% Laskekorko() Jäsenmuuttujat määrittelevät olion ominaisuudet. Jäsenfunktiot määrittelevät, mitä olion kanssa voidaan tehdä. Kapselointi 444

3 Luokat Jokaisen LainaTili-olion ominaisuudet on kuvattu samoilla jäsenmuuttujilla - tässä tapauksessa toinen sisältää lainan saldon ja toinen korkoprosentin. Jokainen olio sisältää myöskin jäsenfunktiot, jotka määrittelevät olion operaatiot: tässä ainut jäsenfunktio laskee koron ja lisää sen lainasaldoon. Ominaisuudet ja operaatiot kapseloidaan jokaiseen LainaTili-olioon. LainaTiliolioon kuuluvat ominaisuudet ja operaatiot ovat tietysti itse päätettävissä. Voit määritellä sen varsin erilaiseksi omassa ohjelmassasi, mutta riippumatta siitä, millaiseksi sen määrittelet, kaikki ominaisuudet ja operaatiot kapseloidaan jokaiseen sentyyppiseen olioon. Tiedon kätkentä Pankki ei tietystikään halua, että lainan saldoa (eikä myöskään korkoprosenttia) muutetaan omavaltaisesti olion ulkopuolelta, kuten pystyimme edellisen kappaleen struktuureiden kohdalla tekemään. Jos tämä sallittaisiin, syntyisi kaaos. Ideaalitilanne on, jos LainaTili-olion jäsenmuuttujat voidaan suojata ulkoiselta käsittelyltä ja että niitä voitaisiin käsitellä ainoastaan kontrolloidusti. Sitä ominaisuutta, että olion jäsenmuuttujat voidaan tehdä sellaisiksi, että niitä ei voi käsitellä suoraan, kutsutaan tiedon kätkennäksi. Yleensä jäsenmuuttujiin ei pääse käsiksi olion ulkopuolelta. LainaTili-olio saldo: mk korkopros: 22% Olion jäsenmuuttujat tulisi yleensä olla kätkettynä. Jäsenfunktioiden avulla voidaan tarpeen mukaan muuttaa jäsenmuuttujien tietoja. laskekorko() käsittelee Jäsenfunktioiden avulla voidaan jäsenmuuttujien sisältöä muuttaa kontrolloidusti. Tiedon kätkentä LainaTili-olion kohdalla voidaan jäsenfunktioiden avulla varmistaa, että jäsenmuuttujia muutetaan vain tietyllä tavalla ja että arvot ovat sallittuja. Korko ei esimerkiksi saa olla negatiivinen ja saldo tarkoittaa pankilta lainattua rahasummaa eikä päinvastoin. Tiedon kätkentä on tärkeä ominaisuus, koska sitä tarvitaan, jos haluat säilyttää olion eheyden. Jos olion on tarkoitus esittää ankkaa, sillä ei tulisi olla neljää jalkaa. Tämän kontrollointi voidaan tehdä siten, että jalkojen lukumäärää ei voida käsitellä suoraan - tieto piilotetaan. Oliolla voi tietysti olla tietoja, joiden arvoaluetta ei voi tarkasti määritellä, mutta myös tällöinkin arvoja voidaan kontrolloida. Esimerkiksi ankka ei yleensä paina yli 100 kiloa. Olioon kuuluvan tiedon kätkentä tarkoittaa sitä, että sitä ei voida käsitellä suoraan, mutta arvoja voidaan käsitellä olion jäsenfunktioiden avulla - joko muuttaa arvoa kontrolloidusti tai vain lukea arvo. Jäsenfunktiot voivat varmistaa, että niiltä pyydetty muutos on sallittu. Olion tietojen kätkentä ei ole pakollista, mutta se on yleensä järkevää ainakin muutamasta syystä. Ensinnäkin, kuten jo mainittiin, olion eheyden säilyttäminen vaatii, että muutoksia voidaan kontrolloida. Toiseksi, olion tietojen käsittely suoraan romuttaa koko olio-ohjelmoinnin idean. Olio-ohjelmoinnin tulee olla olioiden ehdoilla ohjelmoimista, ei olion muodostavien bittien ehdoilla ohjelmoimista. 445

4 C++ Ohjelmoijan käsikirja Jäsenmuuttujien voidaan ajatella kuvaavan olion tilaa ja niitä käsitteleviä jäsenfunktioita olion liittymänä ulkomaailmaan. Luokan avulla ohjelmointi tapahtuu sitten liittymänä toimivien funktioiden kanssa. Luokan liittymää käyttävä ohjelma on täten riippuvainen vain funktion nimistä, niiden parametreistä ja paluuarvoista. Funktioiden sisäinen toiminta ei vaikuta niitä käyttävän ohjelman toimintaan. Tämä tarkoittaa, että luokan liittymä tulee saada oikeaksi jo suunnitteluvaiheessa, mutta luokan toteutusta voit muuttaa haluamallasi tavalla ilman mitään muutoksia sitä käyttävään ohjelmaan. Perityminen Periytymisellä tarkoitetaan mahdollisuutta määritellä tyyppi perustuen jo olemassa olevaan tyyppiin. Oletetaan esimerkiksi, että olet määritellyt tyypin PankkiTili, joka sisältää jäseniä, joita voidaan käyttää kaikentyyppisten pankkitilien yhteydessä. Periytymisen avulla voit sitten luoda tyypin LainaTili, joka on PankkiTili-tyypin erikoismuoto. Voit määritellä LainaTili-tyypin muuten samanlaiseksi kuin PankkiTili, mutta siihen on lisätty muutama ominaisuus ja operaatio. LainaTili-tyyppi perii kaikki PankkiTili-tyypin jäsenet. PankkiTili-tyyppiä kutsutaan uuden luokan kantaluokaksi. Sanomme, että LainaTili on peritty PankkiTili-luokasta. Jokainen LainaTili-olio sisältää kaikki jäsenet, jotka ovat PankkiTili-oliossakin, mutta siihen voidaan määritellä uusia jäseniä tai perityt funktiot voidaan määritellä uudelleen, jotta ne olisivat sopivammat uudelle oliolle. Tämä jälkimmäinen ominaisuus on erittäin hyödyllinen, kuten tulet huomaamaan, kun käsittelemme aihetta lisää. Laajennetaan tätä esimerkkiä ja lisätään siihen uusi tyyppi, ShekkiTili, jossa PankkiTili-tyyppiin on lisätty uusia ominaisuuksia. Koko tilanne havainnollistetaan alla olevassa kaaviossa: saldo korkopros PankkiTili laskekorko() saldo korkopros LainaTili laskekorko() Tyypit LainaTili ja ShekkiTili ovat molemmat periytetty tyypistä PankkiTili, joten ne perivät tämän tyypin jäsenet. saldo korkopros käyttövara ShekkiTili laskekorko() Periytyminen 446

5 Luokat Tyypit LainaTili ja ShekkiTili esitellään siten, että ne periytetään tyypistä PankkiTili. Ne perivät PankkiTili-tyypin jäsenmuuttujat ja jäsenfunktiot, mutta niihin voidaan määritellä uusia, vain niihin liittyviä ominaisuuksia. Tässä esimerkissä luokkaan ShekkiTili on lisätty jäsenmuuttuja kayttovara ja molemmat perityt luokat määrittelevät uudelleen jäsenfunktion laskekorko(), joka muuten perittäisiin kantaluokalta. Tämä on järkevää, koska koron käsittely lainatilin ja shekkitilin kohdalla on varsin erilaista. Polymorfismi Sana polymorfismi tarkoittaa kykyä olettaa erilaisia asioita eri aikoina. C++:n polymorfismiin liittyy aina olion jäsenfunktion kutsuun osoittimen tai viittauksen avulla. Tällaisella funktion kutsulla voi olla erilaisia vaikutuksia eri aikoina - eräänlainen Jekyll ja Hyde -funktiokutsu. Mekanismi toimii vain olioille, joiden tyyppi on periytetty yleisestä tyypistä, kuten meidän PankkiTili-tyypistä. Polymorfismi tarkoittaa, että olioita, jotka kuuluvat periytymissuhteessa oleviin perhe -luokkiin, voidaan käsitellä kantaluokan osoittimien ja viittausten avulla. Äskeisessä esimerkissämme olevia olioita LainaTili ja ShekkiTili voidaan kumpaakin käsitellä osoittimilla tai viittauksilla PankkiTili-olioon. Osoitinta tai viittausta voidaan sitten käyttää minkä tahansa olion, johon se viittaa, perityn jäsenfunktion kutsumiseen. Tämä idea ja sen vaikutukset on helpompi ymmärtää, jos katsomme esimerkkiä. Oletetaan, että meillä on tyypit LainaTili ja ShekkiTili määritelty kuten edellä, eli perustuen PankkiTili-tyyppiin. Oletetaan lisäksi, että olemme määritelleet näiden tyyppiset oliot LTili ja STili, kuten kaaviosta näkyy. Koska molemmat tyypit on periytetty PankkiTili-tyypistä, muuttujaa, jonka tyyppi on osoitin tyyppiin PankkiTili, kuten kaavion pptili, voidaan käyttää kumman tahansa olion osoitteen tallettamiseen. PankkiTili* pptili; LainaTili LTili; ShekkiTili STili; Polymorfismi PankkiTili saldo korkopros laskekorko() pptili = &STili; pptili->laskekorko(); // Hyvittää tiliä pptili = &LTili; pptili->laskekorko(); // Velottaa tiliä LainaTili saldo korkopros laskekorko() saldo korkopros kayttovara laskekorko() ShekkiTili Kaaviossa olevassa koodissa käytetään edellisessä luvussa näkemäämme merkintätäpaa olion jäsenfunktion kutsumisessa osoittimen kautta. 447

6 C++ Ohjelmoijan käsikirja Polymorfismin hienous piilee siinä, että kutsuttava funktio funktion kutsussa pptili- >laskekorko() riippuu siitä, mihin pptili osoittaa. Jos se osoittaa LainaTili-olioon, kutsutaan tämän olion laskekorko()-funktiota ja korko vähennetään tililtä. Jos se osoittaa ShekkiTiliolioon, tulos on eri, koska tämän olion laskekorko()-funktiossa korko lisätään tilille. Kutsuttavaa funktiota ei päätetä ohjelman käännösaikana, vaan ohjelman suoritusaikana. Näin ollen sama funktion kutsu voi kutsua eri asioita riippuen siitä, mihin osoitin osoittaa. Tässä esimerkissä on vain kaksi eri tyyppiä, mutta periaatteessa tyyppejä voi olla niin monta kuin sovelluksesi tarvitsee. Tarvitset hieman lisää tietoa C++-kielestä, jotta voit toteuttaa edellä kuvattua toiminnallisuutta ja juuri tätä on tarkoituskin käsitellä tässä luvussa ja seuraavissa neljässä luvussa. Polymorfismia käytetään omissa ohjelmissasi luvussa 16. Matka sinne alkaa kuitenkin tästä ja käsittelemme ensin avainsanaa class, jolla määritellään uusia luokkia. Terminologiaa Seuraavassa on yhteenveto terminologiasta, jota käytämme C++:n luokkia käsitellessämme. Se sisältää joitakin termejä, joihin olemme törmänneet jo aiemmin. Luokka on käyttäjän määrittelemä tietotyyppi. Luokassa esiteltyjä muuttujia ja funktioita kutsutaan luokan jäseniksi. Muuttujia kutsutaan jäsenmuuttujiksi ja funktioita jäsenfunktioiksi. Luokan jäsenfunktioita kutsutaan joskus myös metodeiksi, mutta tässä kirjassa ei tätä termiä käytetä. Kun olemme määritelleet luokan, voimme esitellä tämän luokkatyypin muuttujan (kutsutaan myös luokan ilmentymäksi). Jokainen ilmentymä on luokan olio. Olio-ohjelmointi on ohjelmointitapa, joka perustuu ideaan, että omat tietotyypit määritellään luokiksi. Siihen kuuluu tiedon kapselointi, luokkien periytyminen ja polymorfismi, joita juuri käsittelimme. Kun pääsemme olio-ohjelmoinnin yksityiskohtiin, koodi saattaa näyttää paikkapaikoin monimutkaiselta. Palaamalla takaisin perusteisiin voidaan asioita selventää; joten käytä yllä olevaa hyödyksesi ja muista mitä oliot itse asiassa ovat. Olio-ohjelmointi on ohjelmien kirjoittamista ongelman olioiden ehdoilla. Kaikki C++:n luokkien toiminnot ovat olemassa siitä syystä, että tämä voidaan suorittaa mahdollisimman joustavasti. Palataan takaisin luokkiin ja aloitetaan luokkien määrittelyllä. 448

7 Luokan määrittely Luokat Kuten olemme jo aikaisemmin maininneet, luokka, samoin kuin struktuuri, on käyttäjän määrittelemä tyyppi. Tyypin määrittely avainsanalla class on perusteiltaan sama kuin määrittely avainsanalla struct, mutta tulos on erilainen. Katsotaan seuraavaksi, kuinka määrittelemme luokan, joka kuvaa laatikkoa. Käytämme tätä tutkiessamme, miten tuloksena oleva luokka eroaa aikaisemmin määrittelemästämme struktuurista. Luodaksemme luokan, kirjoitamme vain avainsanan class avainsanan struct tilalle: class Laatikko double pituus; double syvyys; double korkeus; //Funktio, joka laskee laatikon tilavuuden double tilavuus() return pituus * syvyys * korkeus; ; Olemme tässä ottaneet edellisen luvun Laatikko-struktuurin ja korvanneet avainsanan struct avainsanalla class. Tämän tyyppistä oliota käyttävästä ohjelmasta huomaa heti struktuurin ja luokan merkittävän eron. Et voisi tässä viitata mihinkään jäsenmuuttujaan tai kutsua funktiota tilavuus() luokan ulkopuolelta. Jos yrität, koodi ei käänny. Kun luot luokan, kaikki sen jäsenet ovat oletusarvoisesti kätkettyjä, eli niihin ei pääse käsiksi luokan ulkopuolelta. Niiden sanotaan oleva luokan yksityisiä (private) jäseniä ja niitä voidaan käsitellä vain saman luokan jäsenfunktioista. Jotta luokan jäsen olisi käytettävissä funktiossa, joka ei ole luokan jäsen, sinun tulee määritellä ne luokan julkisiksi (public) jäseniksi avainsanalla public. Struktuurin jäsenet ovat oletusarvoisesti julkisia, joten ne ovat aina käytettävissä. Avainsanoja class ja struct käytetään sellaisten tietotyyppien luonnissa, jotka noudattavat olio-ohjelmoinnin periaatteita. class-tyyppisen olion jäsenet ovat oletusarvoisesti yksityisiä ja struct-tyyppisen olion jäsenet ovat oletusarvoisesti julkisia. Katsotaan seuraavaksi kuinka esittelemme luokan jäsenet julkisiksi: class Laatikko public: double pituus; double syvyys; double korkeus; 449

8 C++ Ohjelmoijan käsikirja ; //Funktio, joka laskee laatikon tilavuuden double tilavuus() return pituus * syvyys * korkeus; Avainsana public on saantitavan hallintakomento. Se määrittelee, onko jäsen käytettävissä ohjelman eri osissa. Luokan jäseniin, jotka ovat julkisia, pääsee käsiksi luokan ulkopuolelta, eli tällaisia jäseniä ei ole kätketty. Luokan jäsen määritellään julkiseksi avainsanalla public, jonka perään kirjoitetaan kaksoispiste. Kaikki tämän hallintakomennon perässä olevat jäsenet seuraavaan hallintakomentoon saakka ovat julkisia. Luokan Laatikko oliot kapseloivat kolme jäsenmuuttujaa ja yhden jäsenfunktion. Jokaisessa Laatikko-oliossa ovat kaikki neljä ja koska olemme määritelleet ne julkisiksi, ne ovat suoraan käytettävissä luokan ulkopuolelta. Käytössä on kaksi muutakin saantitavan hallintakomentoa: private ja protected. Luokan jäsenet, jotka ovat yksityisiä tai suojattuja (protected), ovat kätkettyjä - eli niitä ei voi suoraan käyttää luokan ulkopuolelta. Jos kirjoittaisimme seuraavan rivin edellä olleeseen esimerkkiin, private: niin kaikki tämän rivin perässä olevat jäsenet ovat yksityisiä eikä julkisia. Käsittelemme avainsanan private vaikutuksia tarkemmin myöhemmin tässä luvussa ja protected-avainsanaa käsittelemme luvussa 15. Yleensä luokan määrittelyssä on useampia kuin yksi edellä olleista saantitavan hallintakomennoista. Näin voit sijoittaa jäsenmuuttujat ja jäsenfunktiot omiin ryhmiin saantitavan mukaan. Luokan määrittelyn rakenne on helpompi nähdä, jos järjestät jäsenmuuttujat ja jäsenfunktiot ryhmiin erikseen. Näemme kuinka lähellä struktuuri on luokkaa, kun muutamme edellisen luvun esimerkkiä. Tämä ei ole vielä hyvää luokan suunnittelua, mutta pääsemme lähemmäksi parantamalla luokkaa pala kerrallaan. Samalla näemme kunkin uuden ominaisuuden positiivisen vaikutuksen lopputulokseen. 450 Kokeile itse - Luokan käyttö Seuraavassa on muutettu versio edellisen luvun esimerkistä Tässä käytetään luokkaa struktuurin sijaan: // Esimerkki Laatikkoluokan käyttö #include <iostream> using namespace std; // Laatikon luokka class Laatikko public: double pituus;

9 Luokat double syvyys; double korkeus; ; // Funktio, joka laskee laatikon tilavuuden double tilavuus() return pituus * syvyys * korkeus; int main() Laatikko ensimmainenltk = 80.0, 50.0, 40.0 ; // Lasketaan laatikon tilavuus double ensltktilavuus = ensimmainenltk.tilavuus(); cout cout << "Ensimmäisen Laatikon koko on " << ensimmainenltk.pituus << " x " << ensimmainenltk.syvyys << " x " << ensimmainenltk.korkeus cout << "Ensimmäisen Laatikon tilavuus on " << ensltktilavuus Laatikko toinenltk = ensimmainenltk; // Samaksi kuin 1. laatikko // Kasvatetaan toisen laatikon kokoa 10% toinenltk.pituus *= 1.1; toinenltk.syvyys *= 1.1; toinenltk.korkeus *= 1.1; cout << "Toisen laatikon koko on " << toinenltk.pituus << " by " << toinenltk.syvyys << " by " << toinenltk.korkeus cout << "Toisen laatikon tilavuus on " << toinenltk.tilavuus() cout << "Koon kasvattaminen 10% kasvatti tilavuutta " << static_cast<long>((toinenltk.tilavuus()-ensltktilavuus)*100.0/ ensltktilavuus) << "%" return 0; Ohjelman tulostus on sama kuin edellisessäkin versiossa. Kuinka se toimii main()-funktion koodi on aivan sama kuin ennenkin. Tämä siksi, että olemme esitelleet luokan jäsenet julkisiksi, joten luokka toimii kuten struktuuri. Kaikki struktuurien yhteydessä käsittelemämme pätee tässä myös luokille. Jäseneen osoitus -operaattoria käytetään aivan samaan tapaan luokkien ja struktuurien kohdalla. 451

10 C++ Ohjelmoijan käsikirja Yksi tämän esimerkin osa ei vastaa luokkien yleistä käyttöä. Esittelemme ja alustamme esimerkissä luokan olion seuraavalla alkuarvoluettelolla: Laatikko ensimmainenltk = 80.0, 50.0, 40.0 ; Tämä lause on aivan laillinen, ainakin tässä tapauksessa. Luokan olion jäsenmuuttujia ei yleensä kuitenkaan alusteta tällä tavalla, koska jäsenmuuttujat ovat yleensä kätkettyjä. Kätkettyjä jäsenmuuttujia ei voi alustaa alkuarvoluettelon avulla. Luokan olion jäsenmuuttujien alustus tapahtuu erillisen jäsenfunktion avulla. Tätä jäsenfunktiota kutsutaan muodostinfunktioksi ja sillä voidaan alustaa kätkettyjä jäsenmuuttujia. Muodostinfunktiot Luokan muodostinfunktio on erikoislaatuinen funktio, joka eroaa tavallisesta jäsenfunktiosta. Muodostinfunktiota kutsutaan, kun luokan uusi ilmentymä luodaan. Sen avulla uusi olio voidaan alustaa luonnin yhteydessä ja myöskin varmistaa, että jäsenmuuttujiin sijoitetaan ainoastaan sallittuja arvoja. Sellaisia luokan olioita, joiden luokan määrittelyssä on määritelty muodostinfunktio, ei voi alustaa alkuarvoluettelon avulla. Luokan muodostinfunktiolla on aina sama nimi kuin sen luokalla. Funktio Laatikko() on esimerkiksi luokkamme Laatikko muodostinfunktio. Lisäksi muodostinfunktio ei palauta paluuarvoa, joten sillä ei myöskään ole paluuarvon tyyppiä. Muodostinfunktiolle ei saa määritellä paluuarvon tyyppiä, edes void ei kelpaa. Muodostinfunktion päätehtävä on kaikkien luotavan olion jäsenmuuttujien alustus ja alkuarvojen oikeellisuuden tarkistaminen. Kokeile itse - Muodostinfunktion lisääminen Laatikko-luokkaan Laajennetaan edellisen esimerkkimme Laatikko-luokkaa lisäämällä siihen muodostinfunktio: // Esimerkki Muodostinfunktion käyttö #include <iostream> using namespace std; // Laatikon luokka class Laatikko public: double pituus; double syvyys; double korkeus; 452 //Muodostinfunktio Laatikko(double pituusarvo, double syvyysarvo, double korkeusarvo) cout << Laatikon muodostinfunktiota kutsuttu pituus = pituusarvo; syvyys = syvyysarvo; korkeus = korkeusarvo;

11 Luokat ; // Funktio, joka laskee laatikon tilavuuden double tilavuus() return pituus * syvyys * korkeus; int main() Laatikko ensimmainenltk(80.0, 50.0, 40.0); // Lasketaan laatikon tilavuus double ensltktilavuus = ensimmainenltk.tilavuus(); cout cout << "Ensimmäisen Laatikon koko on " << ensimmainenltk.pituus << " x " << ensimmainenltk.syvyys << " x " << ensimmainenltk.korkeus cout << "Ensimmäisen Laatikon tilavuus on " << ensltktilavuus return 0; Tämän esimerkin tulostus on seuraava: Laatikon muodostinfunktiota kutsuttu Ensimmäisen laatikon koko on 80 x 50 x 40 Ensimmäisen laatikon tilavuus on Kuinka se toimii Laatikko-luokan muodostinfunktion määrittelyssä on kolme double-tyyppistä parametriä, jotka vastaavat jäsenten pituus, syvyys ja korkeus alkuarvoja: Laatikko(double pituusarvo, double syvyysarvo, double korkeusarvo) cout << Laatikon muodostinfunktiota kutsuttu pituus = pituusarvo; syvyys = syvyysarvo; korkeus = korkeusarvo; Kuten huomaat, paluuarvoa ei ole määritelty ja muodostinfunktion nimi on sama kuin luokan nimi. Muodostinfunktion ensimmäisessä lauseessa tulostetaan viesti, josta näemme, milloin sitä on kutsuttu. Tätä et tietysti tee lopullisessa ohjelmassa, mutta koska siitä nähdään helposti, milloin muodostinfunktiota kutsutaan, sitä käytetään usein ohjelman testauksessa. Me käytämme sitä usein havainnollistamaan, mitä esimerkkiohjelmissa tapahtuu. Moudostinfunktion loppukoodi on varsin selkeää. Siinä vain sijoitetaan parametreinä saadut alkuarvot jäsenmuuttujiin. Tarpeen mukaan voisimme lisätä alkuarvojen oikeellisuustarkistuksia. Todellisessa ohjelmassa varmasti tekisitkin näin, mutta tässä päätarkoituksemme on nähdä, miten muodostinfunktio toimii, joten pidämme sen yksinkertaisena. 453

12 C++ Ohjelmoijan käsikirja main()-funktiossa esittelemme olion ensimmainenltk lauseella: Laatikko ensimmainenltk(80.0, 50.0, 40.0); Jäsenmuuttujien pituus, syvyys ja korkeus alkuarvot ovat olion nimen perässä olevissa sulkeissa. Ne välitetään parametreinä muodostinfunktiolle. Kun muodostinfunktiota kutsutaan, se tulostaa viestin, joten näemme, että olion määrittely itse asiassa kutsuu luokkaan lisäämäämme muodostinfunktiota. Koska luokan määrittelyssä on esitelty muodostinfunktio, emme voi alustaa oliota alkuarvoluettelon avulla. Lause, jota käytimme edellisessä esimerkissä, ei enää käänny: Laatikko ensimmainenltk = 80.0, 50.0, 40.0 ; //Väärin!! Täytyy kutsua // muodostinfunktiota Olio, jonka luokkaan on määritelty yksikin muodostinfunktio, täytyy luoda muodostinfunktion avulla. Seuraavat kaksi lausetta main()-funktiossa tulostavat laatikon mitat ja tilavuuden samaan tapaan kuin aikaisemminkin, joten meillä on todisteet siitä, että jäsenmuuttujat sisältävät arvot, jotka välitimme muodostinfunktiolle. Muodostinfunktion määrittelyn sijoittaminen luokan ulkopuolelle Kun käsittelimme edellisessä luvussa struktuureja, näimme, että jäsenfunktio voidaan sijoittaa struktuurin määrittelyn ulkopuolelle. Näin voidaan tehdä myös luokkien ja luokkien muodostinfunktioiden kohdalla. Voimme määritellä luokan Laatikko otsikkotiedostossa: // Laatikko.h #ifndef LAATIKKO_H #define LAATIKKO_H class Laatikko public: double pituus; double syvyys; double korkeus; // Muodostinfunktio Laatikko(double pituusarvo, double syvyysarvo, double korkeusarvo); ; // Funktio, joka laskee laatikon tilavuuden double tilavuus(); #endif 454

13 Nyt voimme sijoittaa jäsenfunktioiden määrittelyt.cpp-tiedostoon. Jokainen funktion nimi, mukaan lukien muodostinfunktioiden nimet, täytyy kirjoittaa luokan nimen ja näkyvyysalueoperaattorin kanssa: // Laatikko.cpp #include <iostream> #include "Laatikko.h" using namespace std; // Muodostinfunktion määrittely Laatikko::Laatikko(double pituusarvo, double syvyysarvo, double korkeusarvo) cout << "Laatikon muodostinfunktiota kutsuttu" pituus = pituusarvo; syvyys = syvyysarvo; korkeus = korkeusarvo; // Funktio, joka laskee laatikon tilavuuden double Laatikko::tilavuus() return pituus * syvyys * korkeus; Luokat Meidän tulee muistaa sisällyttää luokan Laatikko sisältävä otsikkotiedosto, muutoin kääntäjä ei tiedä, että Laatikko on luokka. Luokkien määrittelyn erottaminen jäsenfunktioiden määrittelystä on yhdenmukainen tarkentimien.h ja.cpp kanssa. Näin saamme koodistamme helpommin hallittavan. Kaikkien lähdetekstitiedostojen, jotka haluavat käyttää Laatikko-tyyppiä, tulee sisällyttää otsikkotiedosto Laatikko.h. Ohjelmoijan, joka käyttää tätä luokkaa, ei tarvitse päästä käsiksi jäsenfunktioiden määrittelyyn, luokan määrittelevä otsikkotiedosto riittää. Niin kauan kuin luokan määrittely pysyy kiinteänä, voit vapaasti muuttaa jäsenfunktioiden toteutusta ilman, että sillä on merkitystä luokkaa käyttäviin ohjelmiin. Jäsenfunktion määrittely luokan ulkopuolella ei ole tarkalleen sama kuin määrittelyn sijoittaminen luokan sisälle. Funktion määrittelyt, jotka ovat luokan määrittelyn sisällä, ovat automaattisesti avoimia funktioita (tämä ei kuitenkaan tarkoita, että ne toteutettaisiin avoimina funktioina - kääntäjä päättä tämän yhä funktion ominaisuuksien perusteella. Tätä käsittelimme luvussa 8.). Jäsenfunktiot, jotka määritellään luokan ulkopuolella, voivat olla avoimia ainoastaan, jos ne eksplisiittisesti määritellään sellaisiksi. Tämän luvun loput esimerkit olettavat, että olet jakanut Laatikko-luokan.h ja.cpptiedostoiksi, sekä funktioon main(), joka tällä hetkellä näyttää tältä: // Esimerkki 12.2 Luokan muodostinfunktion käyttö #include <iostream> #include "Laatikko.h" using namespace std; 455

14 C++ Ohjelmoijan käsikirja int main() Laatikko ensimmainenltk(80.0, 50.0, 40.0); // Lasketaan laatikon tilavuus double ensltktilavuus = ensimmainenltk.tilavuus(); cout cout << "Ensimmäisen laatikon koko on " << ensimmainenltk.pituus << " * " << ensimmainenltk.syvyys << " * " << ensimmainenltk.korkeus cout << "Ensimmäisen laatikon tilavuus on " << ensltktilavuus return 0; Oletusmuodostinfunktio Esimerkkimme luokasta, jolla on muodostinfunktio, näyttää varsin suoraviivaiselta, mutta kuten aina, pinnan alla on tärkeitä hienouksia. Kun määrittelemme luokalle muodostinfunktion, muokkaamme luokkaa tavalla, joka ei ole aivan välittömästi selvää. Tarkastellaan nyt tätä. Jokaisella määrittelemälläsi luokalla on vähintään yksi muodostinfunktio, koska luokan olio luodaan aina muodostinfunktiolla. Jos et määrittele luokallesi muodostinfunktiota (kuten esimerkissä 12.1), kääntäjä luo oletusmuodostinfunktion, jota sitten käytetään luokan olioiden luonnissa. Oletusmuodostinfunktiolla ei ole parametrejä. Kun esittelet luokan, kääntäjä luo oletusmuodostinfunktion automaattisesti, mutta vain jos et itse määrittele luokalle muodostinfunktiota. Heti kun lisäät luokallesi muodostinfunktion, kääntäjä olettaa, että oletusmuodostinfunktio on nyt sinun vastuullasi, eikä tee sitä automaattisesti. Seuraava esimerkki selventää, miten oletusmuodostinfunktio voi vaikuttaa koodiisi. Lisätään ohjelmaamme toinen Laatikko-olio, mutta alustetaan se eri tavalla kuin ensimmainenltk. Muuta esimerkin 12.2 main()-funktiota seuraavasti: int main() Laatikko ensimmainenltk(80.0, 50.0, 40.0); // Lasketaan laatikon tilavuus double ensltktilavuus = ensimmainenltk.tilavuus(); cout cout << "Ensimmäisen laatikon koko on " << ensimmainenltk.pituus << " * " << ensimmainenltk.syvyys << " * " << ensimmainenltk.korkeus cout << "Ensimmäisen laatikon tilavuus on " << ensltktilavuus 456

15 Luokat Laatikko pieniltk; pieniltk.pituus = 10.0; pieniltk.syvyys = 5.0; pieniltk.korkeus = 4.0; // Ei käänny, muodostinfunktio on jo määritelty // Lasketaan pienen laatikon tilavuus cout << "Pienen laatikon koko on " << pieniltk.pituus << " * " << pieniltk.syvyys << " * " << pieniltk.korkeus cout << "Pienen laatikon tilavuus on " << pieniltk.tilavuus() return 0; Uusi koodi yrittää luoda uuden olion pieniltk esittelyllä, jossa muodostinfunktiolle ei välitetä parametrejä. Sen sijaan sijoitamme alkuarvot jäsenmuuttujiin eksplisiittisesti kolmella sijoituslauseella. Tämä ei kuitenkaan käänny. Kääntäjän virheilmoitus viittaa seuraavaan riviin: Laatikko pieniltk; // Ei käänny, muodostinfunktio on jo määritelty Tässä kääntäjä etsii oletusmuodostinfunktiota - eli muodostinfunktiota, jolla ei ole parametrejä. Tämä ohjelma käyttää kuitenkin luokkaa Laatikko, johon on määritelty muodostinfunktio: Laatikko::Laatikko(double pituusarvo, double syvyysarvo, double korkeusarvo) cout << "Laatikon muodostinfunktiota kutsuttu" pituus = pituusarvo; syvyys = syvyysarvo; korkeus = korkeusarvo; Koska olemme esitelleet luokalle muodostinfunktion, kääntäjä ei muodosta oletusmuodostinfunktiota, mikä aiheuttaa virheen. Kääntäjän muodostama oletusmuodostinfunktio ei tee mitään - erityisesti, se ei alusta luotavan olion jäsenmuuttujia. Tämähän on kaikkea muuta kuin toivottavaa: tavoitteenammehan on, että voimme kontrolloida muuttujiemme arvoja, joten jos ajattelet käyttäväsi oletusmuodostinfunktiota, joudut tekemään kuitenkin oman muodostinfunktion. Jotta uusi main()-funktiomme toimii, voimme lisätä oman oletusmuodostinfunktiomme luokan määrittelyyn. Kokeile itse - Oletusmuodostinfunktio Lisätään esimerkkiimme oma oletusmuodostinfunktio. Nyt lisäämme vain koodin, joka rekisteröi, että oletusmuodostinfunktiota on kutsuttu. Palaamme jäsenmuuttujien alustukseen myöhemmin. Seuraavassa on Laatikko.h-otsikkotiedoston uusi versio: 457

16 C++ Ohjelmoijan käsikirja class Laatikko public: double pituus; double syvyys; double korkeus; // Muodostinfunktiot Laatikko(); //Oletusmuodostinfunktio Laatikko(double pituusarvo, double syvyysarvo, double korkeusarvo); ; // Funktio, joka laskee laatikon tilavuuden double tilavuus(); Meidän tulee lisäksi lisätä oletusmuodostinfunktion määrittely tiedostoon Laatikko.cpp. // Oletusmuodostinfunktion määrittely Laatikko::Laatikko() cout << "Oletusmuodostinfunktiota on kutsuttu" pituus = syvyys = korkeus = 1; // Oletusmitat Voimme nyt käyttää näitä seuraavassa main()-funktion versiossa: // Esimerkki 12.3 Luokan oletusmuodostinfunktion käyttö #include <iostream> #include "Laatikko.h" using namespace std; int main() Laatikko ensimmainenltk(80.0, 50.0, 40.0); // Lasketaan laatikon tilavuus double ensltktilavuus = ensimmainenltk.tilavuus(); cout cout << "Ensimmäisen laatikon koko on " << ensimmainenltk.pituus << " * " << ensimmainenltk.syvyys << " * " << ensimmainenltk.korkeus cout << "Ensimmäisen laatikon tilavuus on " << ensltktilavuus Laatikko pieniltk; pieniltk.pituus = 10.0; pieniltk.syvyys = 5.0; pieniltk.korkeus = 4.0; 458 // Lasketaan pienen laatikon tilavuus cout << "Pienen laatikon koko on " << pieniltk.pituus << " * " << pieniltk.syvyys << " * "

17 Luokat << pieniltk.korkeus cout << "Pienen laatikon tilavuus on " << pieniltk.tilavuus() return 0; Tulostus näyttää nyt seuraavalta: Laatikon muodostinfunktiota kutsuttu Ensimmäisen laatikon koko on 80 * 50 * 40 Ensimmäisen laatikon tilavuus on Oletusmuodostinfunktiota on kutsuttu Pienen laatikon koko on 10 * 5 * 4 Pienen laatikon tilavuus on 200 Kuinka se toimii Ohjelman tässä versiossa olemme määritelleet omat muodostinfunktiomme, joten kääntäjä ei tee omaa oletusmuodostinfunktiota. Tästä syystä olemme tehneet oman oletusmuodostinfunkiomme. Kääntäjältä ei tule mitään virheilmoituksia ja kaikki toimii. Ohjelman tulostuksesta näemme, että oletusmuodostinfunktiota kutsutaan pieniltk-olion esittelyssä. Oletusmuodostinfunktiomme alustaa kaikki luomansa olion jäsenmuuttujat: pituus = syvyys = korkeus = 1; // Oletusmitat Voimme nyt käyttää oletusmuodostinfunktiota Laatikko-olion määrittelyssä ja alustuksessa: Laatikko pieniltk; Muodostinfunktion, jolla ei ole parametrejä, tärkeä ominaisuus on se, että sitä voidaan kutsua ilman parametrejä - kutsussa ei tarvita edes sulkeita. Yllä oleva lause määrittelee vain luokan tyypin, laatikko, ja olion nimen, pieniltk. Määrittelemällä oletusmuodostinfunktion, joka asettaa arvot jäsenmuuttujiin, voimme varmistaa, että meillä ei ole laatikoita, joiden jäsenmuuttujat sisältävät roskaa. Kun olemme turvallisesti määritelleet ja alustaneet pieniltk-olion, voimme muuttaa mitat haluamiksemme: pieniltk.pituus = 10.0; pieniltk.syvyys = 5.0; pieniltk.korkeus = 4.0; Eräs tämän esimerkin asia on saattanut jäädä sinulta kaiken innostuksen alta huomaamatta: olemme määritelleet muodostinfunktion uudelleen samaan tapaan kuin määrittelimme funktioita uudelleen luvussa 9. Luokalla Laatikko on kaksi muodostinfunktiota, jotka eroavat toisistaan vain parametriluettelon perusteella. Toisessa on kolme double-tyyppistä parametriä ja toisessa ei ole lainkaan parametrejä. 459

18 C++ Ohjelmoijan käsikirja Oletusarvoiset alkuarvot Kun käsittelimme C++:n tavallisia funktioita, näimme miten funktion parametreille voidaan määritellä oletusarvoja funktion prototyypissä. Voimme tehdä tämän myös luokan jäsenfunktioille, muodostinfunktiot mukaan lukien. Jos sijoitamme jäsenfunktion määrittelyn luokan määrittelyn sisälle, voimme sijoittaa parametrien oletusarvot funktion otsikkoon. Jos kirjoitamme ainoastaan funktioiden esittelyt luokan määrittelyyn, parametrien oletusarvojen tulee olla funktion esittelyssä, ei funktion määrittelyssä. Olemme päättäneet oletusmuodostinfunktiossamme, että Laatikko-olion oletuskoko on kuutio, jonka jokaisen sivun pituus on 1. Nyt voimme muuttaa edellisen esimerkin luokan määrittelyn seuraavanlaiseksi: class Laatikko public: double pituus; double syvyys; double korkeus; // Muodostinfunktiot Laatikko(); //Oletusmuodostinfunktio Laatikko(double pituusarvo = 1.0, double syvyysarvo = 1.0, double korkeusarvo = 1.0); ; // Funktio, joka laskee laatikon tilavuuden double tilavuus(); Jos teemme tämän muutoksen edelliseen esimerkkiin, mitä tapahtuu? Saamme tietysti kääntäjän virheilmoituksen! Kääntäjä antaa virheen, että olemme määritelleet oletusmuodostinfunktion useampaan kertaan. main()-funktion koodi saa aikaan virheen, koska meillä on moniselitteinen uudelleenmääritellyn funktion kutsu: Laatikko pieniltk; Syy sekaannukseen on siinä, että tämä lause on kummankin muodostinfunktion sallittu kutsu. Tällaista muodostinfunktion, jolla on parametrien oletusarvot, kutsua ei voida erottaa oletusmuodostinfunktion kutsusta. Koska emme määrittele yhtäkään parametriä, kääntäjä ei pysty päättämään kumpaa funktiota tarkoitetaan. Toisin sanoen, muodostinfunktio, jolla on oletusarvot, toimii myöskin oletusmuodostinfunktiona. Luonnollinen ratkaisu tähän on poistaa muodostinfunktio, jolla ei ole lainkaan parametrejä. Jos teet näin, kaikki kääntyy ja toimii OK. Älä kuitenkaan oleta, että tämä on aina paras tapa toteuttaa oletusmuodostinfunktio. On olemassa monia tilanteita, joissa et halua asettaa oletusarvoja tällä tavalla. Tällöin sinun tulee kirjoittaa erillinen oletusmuodostinfunktio. On myös tilanteita, joissa et halua käyttää oletusmuodostinfunktiota lainkaan, vaikka olisit määritellyt muitakin muodostinfunktioita. Näin voit varmistaa, että kaikki luokan oliot on alustettu niiden esittelyssä eksplisiittisesti. 460

19 Alkuarvolistan käyttö muodostinfunktiossa Luokat Tähän saakka olemme alustaneet olion jäsenet luokan muodostinfunktiossa eksplisiittisellä sijoituksella. Käytössä on kuitenkin toinenkin tekniikka, jossa käytetään alkuarvolistaa. Voimme havainnollistaa tätä luokan Laatikko vaihtoehtoisella muodostinfunktiolla: // Muodostinfunktion määrittely alkuarvolistan avulla Laatikko::Laatikko(double parvo, double sarvo, double karvo) : pituus(parvo), syvyys(sarvo), korkeus(karvo) cout << "Laatikon muodostinfunktiota kutsuttu" Nyt arvoja ei sijoiteta jäsenmuuttujiin muodostinfunktion rungossa olevilla sijoituslauseilla. Ne määritellään funktiomuodossa ja ovat alkuarvolistassa osana funktion otsikkoa. Jäsen pituus alustetaan esimerkiksi arvolla parvo. Huomaa, että muodostinfunktion alkuarvolista erotetaan parametriluettelosta kaksoispisteellä ja alkuarvot erotellaan toisistaan pilkuilla. Tämä on itse asiassa paljon muutakin kuin pelkkä uusi merkintätapa. Alustuksen suorituksessa on tässä tärkeä ero. Kun alustat jäsenmuuttujan sijoituslauseella muodostinfunktion rungossa, jäsenmuuttuja luodaan ensin (kutsumalla muodostinfunktiota, jos se on luokan ilmentymä) ja sen jälkeen sijoitus suoritetaan omana operaationaan. Kun käytät alkuarvolistaa, alkuarvot sijoitetaan jäsenmuuttujiin luonnin yhteydessä. Tämä voi olla huomattavasti tehokkaampaa kuin sijoitus muodostinfunktion rungossa, varsinkin jos jäsenmuuttuja on luokan ilmentymä. Jos muutat edellisen esimerkin muodostinfunktion tällaiseksi, huomaat, että se toimii aivan samalla tavalla. Tämä tekniikka on tärkeä toisestakin syystä. Kuten tulemme huomaamaan, se on ainut tapa alustaa tietyntyyppiset jäsenmuuttujat. explicit-avainsanan käyttö Yksiparametristen muodostinfunktioiden yhteydessä piilee vaara, koska kääntäjä voi käyttää tällaista muodostinfunktiota automaattisena tyypinmuunnoksena parametrin tyypistä luokan tyyppiin. Tämä saattaa joissain tilanteissa saada aikaan epätoivottuja tuloksia. Katsotaan yhtä tällaista tilannetta esimerkin avulla. Oletetaan, että määrittelemme luokan, joka kuvaa kuutiota, jonka kaikki sivut ovat yhtä pitkiä: class Kuutio public: double sivu; ; Kuutio(double sivu); double tilavuus(); bool vertaatil(kuutio akuutio); // Muodostinfunktio // Laskee kuution tilavuuden // Vertaa kuution tilavuutta toiseen 461

20 C++ Ohjelmoijan käsikirja Voimme määritellä muodostinfunktion seuraavasti: Kuutio::Kuutio(double sivu) : pituus(sivu) Kuution tilavuuden laskeva funktio määritellään seuraavasti: double Kuutio::tilavuus() return sivu * sivu * sivu; Lopuksi määrittelemme jäsenfunktion vertaatil() seuraavasti: bool Kuutio::vertaaTil(Kuutio akuutio) return tilavuus() > akuutio.tilavuus(); Muodostinfunktio tarvitsee vain yhden double-tyyppisen parametrin. Kääntäjä voi selvästikin muuntaa muodostinfunktion avulla double-tyyppisen arvon Kuutio-tyypiksi, mutta millaisissa tilanteissa tämä voisi tapahtua? Tarkastellaan Kuutio-luokkaa lisää. Luokassa määritellään myös funktio tilavuus() ja funktio vertaatil(), joka vertaa nykyistä oliota parametrinään saamaan Kuutio-tyyppiseen olioon ja palauttaa arvon true, jos nykyisen olion tilavuus on suurempi. Voisit käyttää sitä esimerkiksi seuraavalla tavalla: Kuutio ltk1(5.0); Kuutio ltk2(3.0); if(ltk1.vertaatil(ltk2)) cout << endl << "ltk1 on suurempi"; else cout << endl << "ltk1 ei ole suurempi"; Tämä on vielä varsin suoraviivaista, mutta mitä tapahtuu, jos joku tätä luokkaa käyttävä kirjoittaa seuraavaa: if(ltk1.vertaatil(50.0)) cout << endl << "ltk1:n tilavuus on suurempi kuin 50"; else cout << endl << "ltk1:n tilavuus ei ole suurempi kuin 50"; Henkilö, joka on kirjoittanut tällaisen koodin, on ymmärtänyt väärin vertaatil()-funktion ja luulee, että se vertaa nykyistä oliota lukuun Kääntäjä tietää, että vertaatil()-funktion parametrin tulee olla Kuutio-olio, mutta se kääntää tämän tyytyväisenä, koska käytössä on muodostinfunktio, joka muuntaa parametrin 50.0 Kuutio-olioksi. Kääntäjän tuottama koodi vastaa seuraavaa koodia: if(ltk1.vertaatil(kuutio(50.0))) cout << endl << "ltk1:n tilavuus on suurempi kuin 50"; else cout << endl << "ltk1:n tilavuus ei ole suurempi kuin 50"; 462 Funktio ei vertaa ltk1:n tilavuutta arvoon 50.0 vaan arvoon , joka on olion Kuutio(50.0) tilavuus! Tulos on kaukana halutusta. Voit kuitenkin estää tämän painajaisen määrittelemällä muodostinfunktion avainsanalla explicit:

21 Luokat class Kuutio public: double sivu; ; explicit Kuutio(double sivu); double tilavuus(); bool vertaatil(kuutio akuutio); // Muodostinfunktio // Laskee kuution tilavuuden // Vertaa kuution tilavuutta toiseen Kääntäjä ei koskaan käytä eksplisiittiseksi määriteltyä muodostinfunktiota automaattisessa tyypinmuunnoksessa. Sitä voidaan käyttää ainoastaan ohjelman koodissa muodostettaessa olio eksplisiittisesti. Koska automaattista tyypinmuunnosta käytetään määritelmän mukaan muunnettaessa annettu tyyppi toiseksi tyypiksi, explicit-avainsanaa tarvitsee käyttää ainoastaan yksiparametristen muodostinfunktioiden yhteydessä. Luokan yksityiset jäsenet Muodostinfunktion yksi tärkeä tehtävä on varmistaa, että olion kaikkiin jäsenmuuttujiin sijoitetaan tarkoituksenmukaiset arvot. Voit esimerkiksi varmistaa, että kaikki Laatikko-olion mitat ovat positiivisia lisäämällä muodostinfunktioon muutamia tarkistuksia: Laatikko::Laatikko(double parvo, double sarvo, double karvo) : pituus(parvo), syvyys(sarvo), korkeus(karvo) cout << "Laatikon muodostinfunktiota kutsuttu." // Varmistetaan positiiviset mitat if(pituus <= 0.0) pituus = 1.0; if(syvyys <= 0.0) syvyys = 1.0; if(korkeus <= 0.0) korkeus = 1.0; Nyt voimme olla varmoja, että riippumatta muodostinfunktiolle välitetyistä parametreistä, Laatikko-olion mitat ovat aina sallitut. Tietysti voisi olla järkevää tulostaa ilmoitus, että tällainen muutos on tehty. Ongelmamme on nyt, että vaikka olemme varmistaneet jäsenmuuttujien alustuksen oikeellisuuden, mikään ei estä niiden muuttamista luokan ulkopuolelta esimerkiksi seuraavilla lauseilla: Laatikko ltk(10.0, 10.0, 5.0); ltk.pituus = //Sijoitetaan kielletty laatikon mitta Voimme tehdä tämän, koska jäsenmuuttujat on määritelty avainsanalla public. Voit estää tällaisen kätkemällä jäsenmuuttujat, mikä tapahtuu yksinkertaisesti määrittelemällä luokan jäsenmuuttujat avainsanalla private. Luokan yksityisiin jäseniin päästään (yleensä) käsiksi vain luokan jäsenmuuttujista. Tavallinen funktio, joka ei ole annetun luokan jäsen, ei voi suoraan käyttää tämän luokan yksityisiä jäseniä. Tämä havainnollistetaan seuraavassa kaaviossa: 463

22 C++ Ohjelmoijan käsikirja Luokan olio Tavallinen funktio, joka ei ole luokan jäsen Ei pääsyä OK OK Julkiset jäsenmuuttujat Julkiset jäsenfunktiot Yksityiset jäsenmuuttujat Yksityiset jäsenfunktiot Käsittely luokan jäsenistä on aina OK. Ei pääsyä Yleisesti ottaen on hyvän olio-ohjelmointitavan mukaista pitää jäsenmuuttujat yksityisinä niin kauan kuin mahdollista. Olio-ohjelmoinnin koko ideahan on loppujen lopuksi siinä, että ohjelmat tehdään olioiden ehdoilla ilman että käsitellään suoraan niiden sisältöä. Luokan julkisia jäseniä, joita tavallisesti ovat funktiot, kutsutaan joskus yleisellä termillä luokan rajapinta. Luokan rajapinnan avulla voit muokata ja käsitellä luokan olioita, joten se määrittelee, mitä voit oliolla tehdä ja mitä olio voi tehdä puolestasi. Pitämällä luokan sisällön yksityisenä, voit myöhemmin muuttaa sitä haluamallasi tavalla välittämättä luokkaa käyttävästä koodista, koska koodi käyttää luokkaa julkisen rajapinnan kautta. Eli luokan julkinen rajapinta on erotettu luokan toteutuksesta. Kokeile itse - Yksityiset jäsenmuuttujat Voimme kirjoittaa Laatikko-luokan jälleen uudelleen. Määritellään jäsenmuuttujat nyt yksityisiksi ja katsotaan, miten luokkaa voidaan nyt käyttää. Tässä ovat muutokset otsikkotiedostoon Laatikko.h: // Laatikko.h #ifndef LAATIKKO_H #define LAATIKKO_H class Laatikko public: // Muodostinfunktio Laatikko(double pituusarvo = 1.0, double syvyysarvo = 1.0, double korkeusarvo = 1.0); // Funktio, joka laskee laatikon tilavuuden double tilavuus(); 464

23 Luokat private: double pituus; double syvyys; double korkeus; ; #endif Voimme myöskin lisätä mittojen tarkistuksen koodiin tiedostossa Laatikko.cpp: // Laatikko.cpp #include <iostream> #include "Laatikko.h" using namespace std; Laatikko::Laatikko(double parvo, double sarvo, double karvo) : pituus(parvo), syvyys(sarvo), korkeus(karvo) cout << "Laatikon muodostinfunktiota kutsuttu." // Varmistetaan positiiviset mitat if(pituus <= 0.0) pituus = 1.0; if(syvyys <= 0.0) syvyys = 1.0; if(korkeus <= 0.0) korkeus = 1.0; // Funktio, joka laskee laatikon tilavuuden double Laatikko::tilavuus() return pituus * syvyys * korkeus; Se, että jäsenfunktioiden määrittelyt ovat luokan ulkopuolella, ei vaikuta luokan jäseniin käsiksi pääsemiseen. Kaikki luokan jäsenet ovat käytettävissä jäsenfunktion rungosta, riippumatta siitä, missä funktion määrittely on. Uuden Laatikko-luokkamme testausta varten voimme kirjoittaa uuden main()-funktion: // Esimerkki Luokan yksityisten jäsenten käyttö #include <iostream> #include "Laatikko.h" using namespace std; int main() cout Laatikko ensimmainenltk(2.2, 1.1, 0.5); Laatikko toinenltk; Laatikko* pkolmasltk = new Laatikko(15.0, 20.0, 8.0); 465

24 C++ Ohjelmoijan käsikirja cout << "Ensimmäisen laatikon tilavuus = " << ensimmainenltk.tilavuus() // toinenltk.pituus = 4.0; // Poista kommentointi ja saat virheen cout << "Toisen laatikon tilavuus = " << toinenltk.tilavuus() cout << "Kolmannen laatikon tilavuus = " << pkolmasltk->tilavuus() delete pkolmasltk; return 0; Ohjelman tulostus näyttää seuraavalta: Laatikon muodostinfunktiota kutsuttu. Laatikon muodostinfunktiota kutsuttu. Laatikon muodostinfunktiota kutsuttu. Ensimmäisen latikon tilavuus on 1.21 Toisen laatikon tilavuus on 1 Kolmannen laatikon tilavuus on 2400 Kuinka se toimii Käytämme public-avainsanaa aloittamaan julkisen osan, jossa meillä ovat jäsenfunktioiden esittelyt: muodostinfunktio ja funktio tilavuus(). Luokan julkisten jäsenten sijoittaminen ennen yksityisiä jäseniä on tarkkaan harkittu - luokan julkiset jäsenet kiinnostavat koodia selaavia enemmän, koska niihin pääsee käsiksi luokan ulkopuolelta. Luokan Laatikko määrittelyssä esitellään kaikki jäsenmuuttujat yksityisiksi käyttämällä privateavainsanaa. Kaikki esittelyt tästä eteenpäin aina seuraavaan saantitavan hallintakomentoon saakka ovat yksityisiä ja niihin ei pääse käsiksi luokan ulkopuolelta. Tätä on tiedon kätkentä käytännössä. Jos poistat kommentoinnin seuraavasta main()-funktion lauseesta, // toinenltk.pituus = 4.0; // Poista kommentointi ja saat virheen koodi ei enää käänny, koska luokan yksityistä jäsenmuuttujaa ei voi käsitellä luokan ulkopuolelta. Ainoa tapa saada arvo Laatikko-olion jäsenmuuttujaan on muodostinfunktion tai jäsenfunktion käyttö. On omalla vastuullasi, että kaikki tavat, joilla haluat yksityisiä jäsenmuuttujia käsitellä, on toteutettu jäsenfunktiolla. 466 Voimme sijoittaa myös funktioita luokan private-osaan, jolloin niitä voidaan kutsua vain toisista jäsenfunktioista. Jos sijoitat funktion tilavuus() private-osaan, lauseet, jotka main()-funktiossa kutsuvat sitä, saavat aikaan kääntäjän virheilmoituksen. Jos sijoitat muodostinfunktion privateosaan, et voi esitellä kyseisen luokan olioita lainkaan.

25 On monia tilanteita, joissa haluat tehdä funktioista yksityisiä. Saatat esimerkiksi tarvita apufunktiota, jota tarvitaan tietyn toiminnan suorittamiseen luokan muissa jäsenfunktioissa, mutta jota ei tarvita luokan ulkopuolella. Palataan takaisin main()-funktioon, jossa ensin esittelemme kaksi Laatikko-oliota seuraavilla lauseilla: Laatikko ensimmainenltk(2.2, 1.1, 0.5); Laatikko toinenltk; Luokat Kumpikin näistä kutsuu samaa muodostinfunktiota (no, eihän niitä olekaan kuin yksi), mutta toinenltk-olion esittely käyttää hyväksi parametrin oletusarvoa, jolloin toinenltk on kuutio, jonka sivujen pituus on 1.0. Seuraava lause esittelee osoittimen Laatikko-olioon, pkolmasltk, ja luo olion vapaasta muistista new-operaattorilla: Laatikko* pkolmasltk = new Laatikko(15.0, 20.0, 8.0); Operaattori new kutsuu samaa Laatikko-muodostinfunktiota, kuten voit tulostuksesta nähdä. Operaattorin palauttama osoite talletetaan muuttujaan pkolmasltk. Nyt tulostamme kaikkien Laatikko-olioiden tilavuudet. Dynaamisesti luomamme olion kohdalla käytämme jäseneen viittaus -operaattoria kutsuessamme funktiota tilavuus(): cout << "Kolmannen laatikon tilavuus = " << pkolmasltk->tilavuus() Tämä esimerkki havainnollisti, että luokka toimii yhä tyydyttävästi, vaikka sen jäsenmuuttujat on määritelty avainsanalla private. Suurin ero on, että ne ovat nyt kokonaan suojassa ulkopuolisilta. Koska kaikki jäsenmuuttujat on kätketty, niitä voi käyttää vain luokan julkisten jäsenfunktioiden kautta. Meidän Laatikko-luokkamme kohdalla tämä tarkoittaa vain yhtä funktiota: muodostinfunktiota. Yksityisten jäsenten käyttö Toisaalta, luokan jäsenmuuttujien määrittely yksityiseksi on varsin voimakasta. On hyvä suojata ne tarpeettomalta käsittelyltä, mutta olemme jo käsitelleet tästä seuraavaa rajoitetta: jos emme tiedä tietyn Laatikko-olion mittoja, emme saa niitä mitenkään selville. Ei sen itse asiassa näin salaista tarvitsisi olla? Älä huolestu: meidän ei tarvitse palata taaksepäin ja esitellä jäsenmuuttujia public-avainsanalla. Voimme poistaa ongelman lisäämällä luokkaan jäsenfunktion, joka palauttaa jäsenmuuttujan arvon. Pääsemme käsiksi Laatikko-olion mittoihin lisäämällä kolme funktiota luokan määrittelyyn: class Laatikko public: 467

26 C++ Ohjelmoijan käsikirja // Muodostinfunktio Laatikko(double pituusarvo = 1.0, double syvyysarvo = 1.0, double korkeusarvo = 1.0); // Funktio, joka laskee laatikon tilavuuden double tilavuus(); //Funktiot, jotka palauttavat jäsenmuuttujien arvot double luepituus() return pituus; double luesyvyys() return syvyys; double luekorkeus() return korkeus; private: double pituus; double syvyys; double korkeus; ; Olemme lisänneet luokkaan funktiot, jotka palauttavat jäsenmuuttujien arvot. Tämä tarkoittaa, että jäsenmuuttujien arvot voidaan vapaasti lukea, mutta niitä ei voida muuttaa, joten niiden eheys säilyy ilman, että ne pidettäisiin salaisina. Tämän tyyppisten funktioiden määrittely on yleensä luokan määrittelyssä, koska ne ovat lyhyitä, ja tämä tekee niistä oletusarvoisesti avoimia funktioita. Näin ollen myös ylimääräinen työ arvojen lukemiseksi on mahdollisimman pieni. Funktioita, joita käytetään jäsenmuuttujien arvon lukemiseen, kutsutaan yleensä saantifunktioiksi. Olisimme voineet käyttää näitä saantifunktioita edellisessä esimerkissäkin, kun tulostimme dynaamisesti luomamme Laatikko-olion mitat: cout << Laatikon koko on << pkolmasltk->luepituus() << * << pkolmasltk->luesyvyys() << * << pkolmasltk->luekorkeus() << * <<endl; Voit käyttää tätä tapaa minkä tahansa luokan kanssa. Riittää kun teet funktion jokaiselle jäsenmuuttujalle, jonka haluat näkyä luokan ulkopuolelle, ja niiden arvoja voidaan käyttää ilman, että luokan turvallisuus kärsii. Jos sijoitat näiden funktioiden määrittelyt luokan määrittelyn ulkopuolelle, sinun tulisi määritellä ne inline-avainsanalla. Jos esimerkiksi olisimme pelkästään esitelleet luepituus()-funktion luokan määrittelyssä, meidän tulisi määritellä se tiedostossa Laatikko.cpp seuraavasti: inline double Laatikko::luePituus() return pituus; Saattaa kuitenkin olla tilanteita, joissa haluat, että jäsenmuuttujia voidaan muuttaa luokan ulkopuolelta. Jos teet jäsenfunktion tällaiseen tarkoitukseen sen sijaan, että jäsenmuuttujia käsiteltäisiin suoraan, voidaan samalla suorittaa arvojen oikeellisuustarkistuksia. Voit esimerkiksi lisätä funktion, jolla muutetaan Laatikko-olion korkeutta: 468 class Laatikko public: // Muodostinfunktio Laatikko(double pituusarvo = 1.0, double syvyysarvo = 1.0, double korkeusarvo = 1.0);

Virtuaalifunktiot ja polymorfismi

Virtuaalifunktiot ja polymorfismi Virtuaalifunktiot ja polymorfismi 16 Virtuaalifunktiot ja polymorfismi Polymorfismi on niin tehokas olio-ohjelmoinnin ominaisuus, että tulet varmastikin käyttämään sitä lähes kaikissa C++-ohjelmissasi.

Lisätiedot

T740103 Olio-ohjelmointi Osa 5: Periytyminen ja polymorfismi Jukka Jauhiainen OAMK Tekniikan yksikkö 2010

T740103 Olio-ohjelmointi Osa 5: Periytyminen ja polymorfismi Jukka Jauhiainen OAMK Tekniikan yksikkö 2010 12. Periytyminen Johdantoa Käytännössä vähänkään laajemmissa ohjelmissa joudutaan laatimaan useita luokkia, joiden pitäisi pystyä välittämään tietoa toisilleen. Ohjelmien ylläpidon kannalta olisi lisäksi

Lisätiedot

815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset

815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset Harjoituksen aiheena ovat aliohjelmat ja abstraktit tietotyypit sekä olio-ohjelmointi. Tehtävät tehdään C-, C++- ja Java-kielillä.

Lisätiedot

Osoitin ja viittaus C++:ssa

Osoitin ja viittaus C++:ssa Osoitin ja viittaus C++:ssa Osoitin yksinkertaiseen tietotyyppiin Osoitin on muuttuja, joka sisältää jonkin toisen samantyyppisen muuttujan osoitteen. Ohessa on esimerkkiohjelma, jossa määritellään kokonaislukumuuttuja

Lisätiedot

Periytyminen. Luokat ja olio-ohjelmointi

Periytyminen. Luokat ja olio-ohjelmointi Periytyminen 15 Periytyminen Tässä luvussa käsittelemme aihetta, joka on olio-ohjelmoinnin kaikkein tärkein osa - periytyvyys. Periytyvyyden avulla voimme luoda uusia luokkia uudelleenkäyttämällä ja laajentamalla

Lisätiedot

12 Mallit (Templates)

12 Mallit (Templates) 12 Mallit (Templates) Malli on määrittely, jota käyttämällä voidaan luoda samankaltaisten aliohjelmien ja luokkien perheitä. Malli on ohje kääntäjälle luoda geneerisestä tyyppiriippumattomasta ohjelmakoodista

Lisätiedot

Mallit standardi mallikirjasto parametroitu tyyppi

Mallit standardi mallikirjasto parametroitu tyyppi Mallit 18 Mallit Malli on tehokas mekanismi uusien luokkien generoimiseksi automaattisesti. Standardikirjaston suuri osa, standardi mallikirjasto, rakentuu kokonaan mallien määrittelymahdollisuuden ympärille,

Lisätiedot

Olio-ohjelmointi Javalla

Olio-ohjelmointi Javalla 1 Olio-ohjelmointi Javalla Olio-ohjelmointi Luokka Attribuutit Konstruktori Olion luominen Metodit Olion kopiointi Staattinen attribuutti ja metodi Yksinkertainen ohjelmaluokka Ohjelmaluokka 1 Olio-ohjelmointi

Lisätiedot

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta C++ - perusteet Java-osaajille luento 5/7: operaattoreiden ylikuormitus, oliotaulukko, parametrien oletusarvot, komentoriviparametrit, constant, inline, Operaattoreiden ylikuormitus Operaattoreiden kuormitus

Lisätiedot

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa();

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa(); Sisällys 7. Oliot ja viitteet Olio Java-kielessä. Olion luominen, elinikä ja tuhoutuminen. Viitteiden käsittelyä: sijoitus, vertailu ja varautuminen null-arvoon. Viite metodin paluuarvona.. 7.1 7.2 Olio

Lisätiedot

11. oppitunti III. Viittaukset. Osa. Mikä on viittaus?

11. oppitunti III. Viittaukset. Osa. Mikä on viittaus? Osa III 11. oppitunti Viittaukset Kahdessa viime luvussa opit käyttämään osoittimia kohteiden käsittelyyn vapaalla muistialueella sekä viittaamaan noihin kohteisiin epäsuorasti. Tässä luvussa käsiteltävät

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 15.3.2010 T-106.1208 Ohjelmoinnin perusteet Y 15.3.2010 1 / 56 Tiedostoista: tietojen tallentaminen ohjelman suorituskertojen välillä Monissa sovelluksissa ohjelman

Lisätiedot

1. Olio-ohjelmointi 1.1

1. Olio-ohjelmointi 1.1 1. Olio-ohjelmointi 1.1 Sisällys Olio-ohjelmointi on eräs ohjelmointiparadigma. Olio-ohjelmoinnin muotoja. Ohjelmiston analyysi ja suunnittelu. Olioparadigman etuja ja kritiikkiä. 1.2 Ohjelmointiparadigmoja

Lisätiedot

Esimerkkiprojekti. Mallivastauksen löydät Wroxin www-sivuilta. Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit

Esimerkkiprojekti. Mallivastauksen löydät Wroxin www-sivuilta. Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit Liite E - Esimerkkiprojekti E Esimerkkiprojekti Olet lukenut koko kirjan. Olet sulattanut kaiken tekstin, Nyt on aika soveltaa oppimiasi uusia asioita pienen, mutta täydellisesti muotoiltuun, projektiin.

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 3 vastaukset Harjoituksen aiheena ovat imperatiivisten kielten muuttujiin liittyvät kysymykset. Tehtävä 1. Määritä muuttujien max_num, lista,

Lisätiedot

Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä

Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä Matti Luukkainen 10.12.2009 Tässä esitetty esimerkki on mukaelma ja lyhennelmä Robert Martinin kirjasta Agile and Iterative Development löytyvästä

Lisätiedot

Harjoitus 7. 1. Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Harjoitus 7. 1. Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti: Harjoitus 7 1. Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti: class Lintu //Kentät private int _siivenpituus; protected double _aivojenkoko; private bool _osaakolentaa; //Ominaisuudet public int

Lisätiedot

Operaattoreiden uudelleenmäärittely

Operaattoreiden uudelleenmäärittely Operaattoreiden uudelleenmäärittely 14 Operaattoreiden uudelleenmäärittely Tässä luvussa käsittelemme, kuinka voit lisätä toiminnallisuutta luokkiisi, jotta ne toimivat enemmän C++:n perustietotyyppien

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 2.3.2009 T-106.1208 Ohjelmoinnin perusteet Y 2.3.2009 1 / 28 Puhelinluettelo, koodi def lue_puhelinnumerot(): print "Anna lisattavat nimet ja numerot." print

Lisätiedot

Omat tietotyypit. Mikä on olio?

Omat tietotyypit. Mikä on olio? Omat tietotyypit 11 Omat tietotyypit C++:n suuri vahvuus on sen oliopohjaisuudessa. Siihen liittyy runsaasti asiaa ja kulutammekin seuraavat viisi lukua tässä aiheessa. Tässä ja seuraavassa luvussa käsittelemme

Lisätiedot

Olio-ohjelmoinnissa luokat voidaan järjestää siten, että ne pystyvät jakamaan yhteisiä tietoja ja aliohjelmia.

Olio-ohjelmoinnissa luokat voidaan järjestää siten, että ne pystyvät jakamaan yhteisiä tietoja ja aliohjelmia. 4. Periytyminen 4.1. Johdantoa Käytännössä vähänkään laajemmissa ohjelmissa joudutaan laatimaan useita luokkia, joiden pitäisi pystyä välittämään tietoa toisilleen. Ohjelmien ylläpidon kannalta olisi lisäksi

Lisätiedot

Osoittimet. Mikä on osoitin?

Osoittimet. Mikä on osoitin? Osoittimet 7 Osoittimet On aika siirtyä käsittelemään osoittimia, C++:lle elintärkeätä ominaisuutta. Osoittimet ovat tärkeitä, koska ne luovat perustan muistin dynaamiselle varaukselle ja käytölle. Ne

Lisätiedot

Ohjelman virheet ja poikkeusten käsittely

Ohjelman virheet ja poikkeusten käsittely Ohjelman virheet ja poikkeusten käsittely 17 Ohjelman virheet ja poikkeusten käsittely Poikkeukset ovat tapa ilmoittaa virheistä ja odottamattomista tilanteista C++-ohjelmassasi. Poikkeusten käyttö virheiden

Lisätiedot

Operaattorin ylikuormitus ja käyttäjän muunnokset

Operaattorin ylikuormitus ja käyttäjän muunnokset 13 Operaattorin ylikuormitus ja käyttäjän muunnokset Luvussa 7, "Ominaisuudet, taulukot ja indeksoijat," opit, miten luokan yhteydessä käytetään ohjelmallisesti []-operaattoria, jolloin objektia voidaan

Lisätiedot

on ohjelmoijan itse tekemä tietotyyppi, joka kuvaa käsitettä

on ohjelmoijan itse tekemä tietotyyppi, joka kuvaa käsitettä LUOKAN MÄÄRITTELY Luokka, mitä se sisältää Luokan määrittely Olion ominaisuudet eli attribuutit Olion metodit Olion muodostimet ja luonti Olion tuhoutuminen Metodin kutsu luokan ulkopuolelta Olion kopioiminen

Lisätiedot

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CSE-A1111 30.9.2015 CSE-A1111 Ohjelmoinnin peruskurssi Y1 30.9.2015 1 / 27 Mahdollisuus antaa luentopalautetta Goblinissa vasemmassa reunassa olevassa valikossa on valinta Luentopalaute.

Lisätiedot

4. Luokan testaus ja käyttö olion kautta 4.1

4. Luokan testaus ja käyttö olion kautta 4.1 4. Luokan testaus ja käyttö olion kautta 4.1 Olion luominen luokasta Java-kielessä olio määritellään joko luokan edustajaksi tai taulukoksi. Olio on joukko keskusmuistissa olevia tietoja. Oliota käsitellään

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 7. huhtikuuta 2017 Vastaa kaikkiin tehtäviin. Tee jokainen tehtävä erilliselle konseptiarkille. Kirjoittamasi luokat, funktiot ja aliohjelmat

Lisätiedot

2. Olio-ohjelmoinista lyhyesti 2.1

2. Olio-ohjelmoinista lyhyesti 2.1 2. Olio-ohjelmoinista lyhyesti 2.1 Sisällys Yleistä. Oliot ja luokat. Attribuutit. Olioiden esittely ja alustus. Rakentajat. Olion operaation kutsuminen. 2.2 Yleistä Olio-ohjelmointia käsitellään hyvin

Lisätiedot

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan.

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan. Osoittimet Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan. Muistilohkon koko riippuu muuttujan tyypistä, eli kuinka suuria arvoja muuttujan

Lisätiedot

T Olio-ohjelmointi Osa 3: Luokka, muodostin ja hajotin, this-osoitin Jukka Jauhiainen OAMK Tekniikan yksikkö 2010

T Olio-ohjelmointi Osa 3: Luokka, muodostin ja hajotin, this-osoitin Jukka Jauhiainen OAMK Tekniikan yksikkö 2010 11. Luokka Opetellaan seuraavaksi, miten omia luokkia kirjoitetaan. Aikaisemmin olikin jo esillä, että luokka on tietorakenne, joka sisältää sekä tiedot (attribuutit) että niitä käsittelevät aliohjelmat

Lisätiedot

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4) 2. Lisää Java-ohjelmoinnin alkeita Muuttuja ja viittausmuuttuja Vakio ja literaalivakio Sijoituslause Syötteen lukeminen ja Scanner-luokka 1 Muuttuja ja viittausmuuttuja (1/4) Edellä mainittiin, että String-tietotyyppi

Lisätiedot

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen Taulukot: Array Taulukko Javassa pitää aina perustaa (new) Yksinkertaisessa tilanteessa taulukon koko tiedetään etukäteen ja

Lisätiedot

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista Sisällys 1. Omat operaatiot Yleistä operaatioista. Mihin operaatioita tarvitaan? Oman operaation määrittely. Yleisesti, nimeäminen ja hyvä ohjelmointitapa, määreet, parametrit ja näkyvyys. HelloWorld-ohjelma

Lisätiedot

Javan perusteita. Janne Käki

Javan perusteita. Janne Käki Javan perusteita Janne Käki 20.9.2006 Muutama perusasia Tietokone tekee juuri (ja vain) sen, mitä käsketään. Tietokone ymmärtää vain syntaksia (sanojen kirjoitusasua), ei semantiikkaa (sanojen merkitystä).

Lisätiedot

Sisällys. Metodien kuormittaminen. Luokkametodit ja -attribuutit. Rakentajat. Metodien ja muun luokan sisällön järjestäminen. 6.2

Sisällys. Metodien kuormittaminen. Luokkametodit ja -attribuutit. Rakentajat. Metodien ja muun luokan sisällön järjestäminen. 6.2 6. Metodit 6.1 Sisällys Metodien kuormittaminen. Luokkametodit ja -attribuutit. Rakentajat. Metodien ja muun luokan sisällön järjestäminen. 6.2 Oliot viestivät metodeja kutsuen Olio-ohjelmoinnissa ohjelma

Lisätiedot

9. Periytyminen Javassa 9.1

9. Periytyminen Javassa 9.1 9. Periytyminen Javassa 9.1 Sisällys Periytymismekanismi Java-kielessä. Piirteiden näkyvyys periytymisessä. Ilmentymämetodien korvaaminen. Luokkametodien peittäminen. Super-attribuutti. Override-annotaatio.

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 16.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 16.2.2010 1 / 41 Kännykkäpalautetteen antajia kaivataan edelleen! Ilmoittaudu mukaan lähettämällä ilmainen tekstiviesti

Lisätiedot

1. Omat operaatiot 1.1

1. Omat operaatiot 1.1 1. Omat operaatiot 1.1 Sisällys Yleistä operaatioista. Mihin operaatioita tarvitaan? Oman operaation määrittely. Yleisesti, nimeäminen ja hyvä ohjelmointitapa, määreet, parametrit ja näkyvyys. HelloWorld-ohjelma

Lisätiedot

Tehtävä 1. TL5302 Olio-ohjelmointi Koe Malliratkaisuja. Tässä sekä a)- että b)-kohdan toimiva ratkaisu:

Tehtävä 1. TL5302 Olio-ohjelmointi Koe Malliratkaisuja. Tässä sekä a)- että b)-kohdan toimiva ratkaisu: TL5302 Olio-ohjelmointi Koe 19.4.2005 Malliratkaisuja Tehtävä 1 Tässä sekä a)- että b)-kohdan toimiva ratkaisu: #include using namespace std; int main() int taul[5]=1,2,3,4,5; int *p,&r=taul[0];

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 20. huhtikuuta 2018 Vastaa kaikkiin tehtäviin. Tee kukin tehtävä omalle konseptiarkille. Noudata ohjelmointitehtävissä kurssin koodauskäytänteitä.

Lisätiedot

Luokassa määriteltävät jäsenet ovat pääasiassa tietojäseniä tai aliohjelmajäseniä. Luokan määrittelyyn liittyvät varatut sanat:

Luokassa määriteltävät jäsenet ovat pääasiassa tietojäseniä tai aliohjelmajäseniä. Luokan määrittelyyn liittyvät varatut sanat: 1. Luokan jäsenet Luokassa määriteltävät jäsenet ovat pääasiassa tietojäseniä tai aliohjelmajäseniä. Luokan määrittelyyn liittyvät varatut sanat: class luokan_nimi tyypit: enum, struct, class, typedef

Lisätiedot

Olio-ohjelmointi 2. välikoe HYV5SN

Olio-ohjelmointi 2. välikoe HYV5SN Olio-ohjelmointi 2. välikoe 27.4.2007 HYV5SN 1. Tee ohjelma, joka sisältää laatikko-luokan. Luokan tietojäseninä ovat laatikon syvyys, leveys ja korkeus. Toteuta luokkaan muodostin, jonka avulla olio voidaan

Lisätiedot

13 Operaattoreiden ylimäärittelyjä

13 Operaattoreiden ylimäärittelyjä 248 13 C++-kielessä voidaan operaattoreita ylimäärittää. Ylimääriteltävää operaattoria voidaan pitää ikäänkuin metodina, joka esitellään luokan esittelyssä ja määritellään luokan ulkopuolella kuten metoditkin.

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 1.4.2009 T-106.1208 Ohjelmoinnin perusteet Y 1.4.2009 1 / 56 Tentti Ensimmäinen tenttimahdollisuus on pe 8.5. klo 13:00 17:00 päärakennuksessa. Tämän jälkeen

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 12. huhtikuuta 2019 Tee kukin tehtävä omalle konseptiarkille. Noudata ohjelmointitehtävissä kurssin koodauskäytänteitä. Yksi A4-kokoinen lunttilappu

Lisätiedot

Taulukot. Jukka Harju, Jukka Juslin 2006 1

Taulukot. Jukka Harju, Jukka Juslin 2006 1 Taulukot Jukka Harju, Jukka Juslin 2006 1 Taulukot Taulukot ovat olioita, jotka auttavat organisoimaan suuria määriä tietoa. Käsittelylistalla on: Taulukon tekeminen ja käyttö Rajojen tarkastus ja kapasiteetti

Lisätiedot

Tietueet. Tietueiden määrittely

Tietueet. Tietueiden määrittely Tietueet Tietueiden määrittely Tietue on tietorakenne, joka kokoaa yhteen eri tyyppistä tietoa yhdeksi asiakokonaisuudeksi. Tähän kokonaisuuteen voidaan viitata yhteisellä nimellä. Auttaa ohjelmoijaa järjestelemään

Lisätiedot

Ohjelmointikielet ja -paradigmat 5op. Markus Norrena

Ohjelmointikielet ja -paradigmat 5op. Markus Norrena Ohjelmointikielet ja -paradigmat 5op Markus Norrena Ko#tehtävä 4 Viimeistele "alkeellinen kuvagalleria". Käytännössä kaksi sivua Yksi jolla voi ladata kuvia palvelimelle (file upload) Toinen jolla ladattuja

Lisätiedot

SQL-perusteet, SELECT-, INSERT-, CREATE-lauseet

SQL-perusteet, SELECT-, INSERT-, CREATE-lauseet SQL-perusteet, SELECT-, INSERT-, CREATE-lauseet A271117, Tietokannat Teemu Saarelainen teemu.saarelainen@kyamk.fi Lähteet: Leon Atkinson: core MySQL Ari Hovi: SQL-opas TTY:n tietokantojen perusteet-kurssin

Lisätiedot

Ohjelmointi 2. Jussi Pohjolainen. TAMK» Tieto- ja viestintäteknologia , Jussi Pohjolainen TAMPEREEN AMMATTIKORKEAKOULU

Ohjelmointi 2. Jussi Pohjolainen. TAMK» Tieto- ja viestintäteknologia , Jussi Pohjolainen TAMPEREEN AMMATTIKORKEAKOULU Ohjelmointi 2 Jussi Pohjolainen TAMK» Tieto- ja viestintäteknologia Tietotyypeistä C++ - kielessä useita tietotyyppejä Kirjaimet: char, wchar_t Kokonaisluvut: short, int, long Liukuluvut: float, double

Lisätiedot

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti Luku 6 Dynaaminen ohjelmointi Dynaamisessa ohjelmoinnissa on ideana jakaa ongelman ratkaisu pienempiin osaongelmiin, jotka voidaan ratkaista toisistaan riippumattomasti. Jokaisen osaongelman ratkaisu tallennetaan

Lisätiedot

Muuttujien roolit Kiintoarvo cin >> r;

Muuttujien roolit Kiintoarvo cin >> r; Muuttujien roolit Muuttujilla on ohjelmissa eräitä tyypillisiä käyttötapoja, joita kutsutaan muuttujien rooleiksi. Esimerkiksi muuttuja, jonka arvoa ei muuteta enää kertaakaan muuttujan alustamisen jälkeen,

Lisätiedot

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A274615 JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A274615 JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++? JAVA-OHJELMOINTI 3op A274615 JAVAN PERUSTEET LYHYT KERTAUS Teemu Saarelainen teemu.saarelainen@kyamk.fi Lähteet: http://java.sun.com/docs/books/tutorial/index.html Vesterholm, Kyppö: Java-ohjelmointi,

Lisätiedot

C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa.

C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa. Taulukot C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa. Taulukon muuttujilla (muistipaikoilla) on yhteinen nimi. Jokaiseen yksittäiseen

Lisätiedot

Olio-ohjelmointi Syntaksikokoelma

Olio-ohjelmointi Syntaksikokoelma C++-kielen uusia ominaisuuksia Olio-ohjelmointi Syntaksikokoelma 31.10.2008 Bool-tietotyyppi: Totuusarvo true (1), jos ehto on tosi ja false (0) jos ehto epätosi. Dynaaminen muistinvaraus: Yhden muuttuja

Lisätiedot

Johdatus Ohjelmointiin

Johdatus Ohjelmointiin Johdatus Ohjelmointiin Syksy 2006 Viikko 2 13.9. - 14.9. Tällä viikolla käsiteltävät asiat Peruskäsitteitä Kiintoarvot Tiedon tulostus Yksinkertaiset laskutoimitukset Muuttujat Tiedon syöttäminen Hyvin

Lisätiedot

Kääntäjän virheilmoituksia

Kääntäjän virheilmoituksia OHJ-1101 Ohjelmointi 1e 2008-09 1 Kääntäjän virheilmoituksia Kun progvh2 ohjelma käännetään antaa tutg++ seuraavat virheilmoitukset ja varoitukset: proffa> tutg++ progvh2.cc progvh2.cc:29:13: warning:

Lisätiedot

Java-kielen perusteet

Java-kielen perusteet Java-kielen perusteet Tunnus, varattu sana, kommentti Muuttuja, alkeistietotyyppi, merkkijono, literaalivakio, nimetty vakio Tiedon merkkipohjainen tulostaminen 1 Tunnus Java tunnus Java-kirjain Java-numero

Lisätiedot

Sisällys. 7. Oliot ja viitteet. Olion luominen. Olio Java-kielessä

Sisällys. 7. Oliot ja viitteet. Olion luominen. Olio Java-kielessä Sisälls 7. Oliot ja viitteet Olio Java-kielessä. Olion luominen, elinikä ja tuhoutuminen.. Viitteiden vertailu. Varautuminen null-arvoon. Viite metodin paluuarvona.. Muuttumattomat ja muuttuvat merkkijonot.

Lisätiedot

UML Luokkakaavio 14:41

UML Luokkakaavio 14:41 UML Luokkakaavio UML Olio-ohjelman luokkien pääpiirteet voidaan kätevähkösti esittää ns. UML-luokkakaaviona. Näin usein tehdäänkin esim. suunniteltaessa, millaisia luokkia ohjelmaan on tarkoitus laatia,

Lisätiedot

Ohjelmoinnin jatkokurssi, kurssikoe 28.4.2014

Ohjelmoinnin jatkokurssi, kurssikoe 28.4.2014 Ohjelmoinnin jatkokurssi, kurssikoe 28.4.2014 Kirjoita jokaiseen palauttamaasi konseptiin kurssin nimi, kokeen päivämäärä, oma nimi ja opiskelijanumero. Vastaa kaikkiin tehtäviin omille konsepteilleen.

Lisätiedot

7. Oliot ja viitteet 7.1

7. Oliot ja viitteet 7.1 7. Oliot ja viitteet 7.1 Sisällys Olio Java-kielessä. Olion luominen, elinikä ja tuhoutuminen. Viitteiden sijoitus. Viitteiden vertailu. Varautuminen null-arvoon. Viite metodin paluuarvona. Viite metodin

Lisätiedot

1 Tehtävän kuvaus ja analysointi

1 Tehtävän kuvaus ja analysointi Olio-ohjelmoinnin harjoitustyön dokumentti Jyri Lehtonen (72039) Taneli Tuovinen (67160) 1 Tehtävän kuvaus ja analysointi 1.1 Tehtävänanto Tee luokka, jolla mallinnetaan sarjaan kytkettyjä kondensaattoreita.

Lisätiedot

Tietotyypit ja operaattorit

Tietotyypit ja operaattorit Tietotyypit ja operaattorit Luennossa tarkastellaan yksinkertaisten tietotyyppien int, double ja char muunnoksia tyypistä toiseen sekä esitellään uusia operaatioita. Numeeriset tietotyypit ja muunnos Merkkitieto

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 15.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 15.2.2010 1 / 46 Merkkijonot Merkkijonojen avulla ohjelmassa voi esittää tekstitietoa, esim. nimiä, osoitteita ja

Lisätiedot

15. Ohjelmoinnin tekniikkaa 15.1

15. Ohjelmoinnin tekniikkaa 15.1 15. Ohjelmoinnin tekniikkaa 15.1 Sisällys For-each-rakenne. Lueteltu tyyppi enum. Override-annotaatio. Geneerinen ohjelmointi. 15.2 For-each-rakenne For-rakenteen variaatio taulukoiden ja muiden kokoelmien

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 28.2.2011 T-106.1208 Ohjelmoinnin perusteet Y 28.2.2011 1 / 46 Ohjelmointiprojektin vaiheet 1. Määrittely 2. Ohjelman suunnittelu (ohjelman rakenne ja ohjelman

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 22. huhtikuuta 2016 Vastaa kaikkiin tehtäviin. Tee jokainen tehtävä erilliselle konseptiarkille! Kirjoittamasi luokat, funktiot ja aliohjelmat

Lisätiedot

Luokan operaatiot. Osoittimet ja viittaukset luokan olioihin

Luokan operaatiot. Osoittimet ja viittaukset luokan olioihin Luokan operaatiot 13 Luokan operaatiot Luokkien olioiden luomiseen ja tuhoamiseen liittyy monia hienouksia, joista sinun tulee olla selvillä, jotta luokkiesi olioiden operaatiot toimivat turvallisesti

Lisätiedot

Olio-ohjelmointi: Luokkien toteuttaminen. Jukka Juslin

Olio-ohjelmointi: Luokkien toteuttaminen. Jukka Juslin Olio-ohjelmointi: Luokkien toteuttaminen Jukka Juslin Luokkien kirjoittaminen Tähän mennessä on käytetty valmiiksi määritettyjä luokkia. Nyt opimme kirjoittamaan omia luokkia olioiden kuvaamiseksi Seuraavaksi

Lisätiedot

15. Ohjelmoinnin tekniikkaa 15.1

15. Ohjelmoinnin tekniikkaa 15.1 15. Ohjelmoinnin tekniikkaa 15.1 Sisällys For-each-rakenne. Geneerinen ohjelmointi. Lueteltu tyyppi enum. 15.2 For-each-rakenne For-rakenteen variaatio taulukoiden ja muiden kokoelmien silmukoimiseen:

Lisätiedot

14. Poikkeukset 14.1

14. Poikkeukset 14.1 14. Poikkeukset 14.1 Sisällys Johdanto. Tarkistettavat ja tarkistamattomat poikkeukset. Poikkeusten tunnistaminen ja sieppaaminen try-catchlauseella. Mitä tehdä siepatulla poikkeuksella? Poikkeusten heittäminen.

Lisätiedot

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä Sisällys 9. Periytyminen Javassa Periytymismekanismi Java-kielessä. Piirteiden näkyvyys periytymisessä. Metodien korvaaminen ja super-attribuutti. Attribuutin peittäminen periytymisen kautta. Rakentajat

Lisätiedot

Osa. Listaus 2.1. HELLO.CPP esittelee C++ -ohjelman osat. 14: #include <iostream.h> 15: 16: int main() 17: {

Osa. Listaus 2.1. HELLO.CPP esittelee C++ -ohjelman osat. 14: #include <iostream.h> 15: 16: int main() 17: { Osa I 2. oppitunti C++-ohjelman osat Ennen kuin menemme yksityiskohtaisemmin sisälle C++-luokkiin, -muuttujiin jne, katsokaamme ensin, millaisista osista C++-ohjelma koostuu. Tämän tunnin aikana opit seuraavat

Lisätiedot

Ohjelmointi 2 / 2010 Välikoe / 26.3

Ohjelmointi 2 / 2010 Välikoe / 26.3 Ohjelmointi 2 / 2010 Välikoe / 26.3 Välikoe / 26.3 Vastaa neljään (4) tehtävään ja halutessa bonustehtäviin B1 ja/tai B2, (tuovat lisäpisteitä). Bonustehtävät saa tehdä vaikkei olisi tehnyt siihen tehtävään

Lisätiedot

Java-kielen perusteet

Java-kielen perusteet Java-kielen perusteet Tunnus, varattu sana, kommentti Muuttuja, alkeistietotyyppi, merkkijono, Vakio Tiedon merkkipohjainen tulostaminen Ohjelmointi (ict1tx006) Tunnus (5.3) Javan tunnus Java-kirjain Java-numero

Lisätiedot

Sisältö. 2. Taulukot. Yleistä. Yleistä

Sisältö. 2. Taulukot. Yleistä. Yleistä Sisältö 2. Taulukot Yleistä. Esittely ja luominen. Alkioiden käsittely. Kaksiulotteinen taulukko. Taulukko operaation parametrina. Taulukko ja HelloWorld-ohjelma. Taulukko paluuarvona. 2.1 2.2 Yleistä

Lisätiedot

4. Olio-ohjelmoinista lyhyesti 4.1

4. Olio-ohjelmoinista lyhyesti 4.1 4. Olio-ohjelmoinista lyhyesti 4.1 Sisällys Yleistä. Oliot ja luokat. Attribuutit. Olioiden esittely ja alustus. Rakentajat. Olion operaation kutsuminen. 4.2 Yleistä Olio-ohjelmointia käsitellään hyvin

Lisätiedot

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CSE-A1111 21.9.2015 CSE-A1111 Ohjelmoinnin peruskurssi Y1 21.9.2015 1 / 25 Mahdollisuus antaa luentopalautetta Goblinissa vasemmassa reunassa olevassa valikossa on valinta Luentopalaute.

Lisätiedot

Sisällys. 6. Metodit. Oliot viestivät metodeja kutsuen. Oliot viestivät metodeja kutsuen

Sisällys. 6. Metodit. Oliot viestivät metodeja kutsuen. Oliot viestivät metodeja kutsuen Sisällys 6. Metodit Oliot viestivät metodeja kutsuen. Kuormittaminen. Luokkametodit (ja -attribuutit).. Metodien ja muun luokan sisällön järjestäminen. 6.1 6.2 Oliot viestivät metodeja kutsuen Oliot viestivät

Lisätiedot

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä Sisällys 9. Periytyminen Javassa Periytymismekanismi Java-kielessä. Piirteiden näkyvyys periytymisessä. Metodien korvaaminen ja super-attribuutti. Attribuutin peittäminen periytymisen kautta. Rakentajat

Lisätiedot

C++ rautaisannos. Kolme tapaa sanoa, että tulostukseen käytetään standardikirjaston iostreamosassa määriteltyä, nimiavaruuden std oliota cout:

C++ rautaisannos. Kolme tapaa sanoa, että tulostukseen käytetään standardikirjaston iostreamosassa määriteltyä, nimiavaruuden std oliota cout: C++ rautaisannos Kolme tapaa sanoa, että tulostukseen käytetään standardikirjaston iostreamosassa määriteltyä, nimiavaruuden std oliota cout: # include #include main ( ) main (

Lisätiedot

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

Sisällys. 14. Poikkeukset. Johdanto. Johdanto Sisällys 14. Poikkeukset Johdanto. Tarkistettavat ja tarkistamattomat poikkeukset. Poikkeusten tunnistaminen ja sieppaaminen try-catchlauseella. Mitä tehdä siepatulla poikkeuksella? Poikkeusten heittäminen.

Lisätiedot

Funktiomallit. 10.1 Funktiomallin määrittely

Funktiomallit. 10.1 Funktiomallin määrittely 10 Funktiomallit Tässä luvussa kuvataan, mikä funktiomalli on, ja tuodaan esille, kuinka niitä määritellään ja käytetään. Funktiomallin käyttö on melko yksinkertaista ja monet aloittelevat C++-ohjelmoijat

Lisätiedot

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen Metodit Metodien määrittely Metodin parametrit ja paluuarvo Metodien suorittaminen eli kutsuminen Metodien kuormittaminen 1 Mikä on metodi? Metodi on luokan sisällä oleva yhteenkuuluvien toimintojen kokonaisuus

Lisätiedot

Pong-peli, vaihe Aliohjelman tekeminen. Muilla kielillä: English Suomi. Tämä on Pong-pelin tutoriaalin osa 3/7. Tämän vaiheen aikana

Pong-peli, vaihe Aliohjelman tekeminen. Muilla kielillä: English Suomi. Tämä on Pong-pelin tutoriaalin osa 3/7. Tämän vaiheen aikana Muilla kielillä: English Suomi Pong-peli, vaihe 3 Tämä on Pong-pelin tutoriaalin osa 3/7. Tämän vaiheen aikana Jaetaan ohjelma pienempiin palasiin (aliohjelmiin) Lisätään peliin maila (jota ei voi vielä

Lisätiedot

Ohjelmistojen mallintaminen Olioiden yhteistyö. 18.11.2008 Harri Laine 1

Ohjelmistojen mallintaminen Olioiden yhteistyö. 18.11.2008 Harri Laine 1 Ohjelmistojen mallintaminen Olioiden yhteistyö 18.11.2008 Harri Laine 1 Olioiden yhteistyö Oliokeskeisen ohjelmistonäkemyksen mukaan ohjelmiston palvelut tuotetaan olioiden yhteistyön tuloksena. Ohjelmisto

Lisätiedot

\+jokin merkki tarkoittaa erikoismerkkiä; \n = uusi rivi.

\+jokin merkki tarkoittaa erikoismerkkiä; \n = uusi rivi. 1. Johdanto 1.1 Yleistä Suurten ohjelmien organisointi vaikeaa C:ssä. 1980 Stroustrup lisäsi C:hen olio-ohjelmoinnin (OOP = Object Oriented Programming). C C++: C-ohjelma on (muutamia poikkeuksia lukuunottamatta)

Lisätiedot

9. Periytyminen Javassa 9.1

9. Periytyminen Javassa 9.1 9. Periytyminen Javassa 9.1 Sisällys Periytymismekanismi Java-kielessä. Piirteiden näkyvyys periytymisessä. Metodien korvaaminen ja super-attribuutti. Attribuutin peittäminen periytymisen kautta. Rakentajat

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 9.2.2009 T-106.1208 Ohjelmoinnin perusteet Y 9.2.2009 1 / 35 Listat Esimerkki: halutaan kirjoittaa ohjelma, joka lukee käyttäjältä 30 lämpötilaa. Kun lämpötilat

Lisätiedot

Tenttikysymykset. + UML-kaavioiden mallintamistehtävät

Tenttikysymykset. + UML-kaavioiden mallintamistehtävät Tenttikysymykset 1. Selitä mitä asioita kuuluu tietojärjestelmän käsitteeseen. 2. Selitä kapseloinnin ja tiedon suojauksen periaatteet oliolähestymistavassa ja mitä hyötyä näistä periaatteista on. 3. Selitä

Lisätiedot

C# olio-ohjelmointi perusopas

C# olio-ohjelmointi perusopas Paavo Räisänen C# olio-ohjelmointi perusopas www.ohjelmoimaan.net Tätä opasta saa vapaasti kopioida, tulostaa ja levittää ei kaupallisissa tarkoituksissa. Kuitenkaan omille nettisivuille opasta ei saa

Lisätiedot

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma. 2. Taulukot 2.1 Sisältö Yleistä. Esittely ja luominen. Alkioiden käsittely. Kaksiulotteinen taulukko. Taulukko operaation parametrina. Taulukko ja HelloWorld-ohjelma. Taulukko paluuarvona. 2.2 Yleistä

Lisätiedot

812341A Olio-ohjelmointi Peruskäsitteet jatkoa

812341A Olio-ohjelmointi Peruskäsitteet jatkoa 812341A Olio-ohjelmointi 2106 Peruskäsitteet jatkoa Luokkakohtaiset piirteet n Yhteisiä kaikille saman luokan olioille n Liittyvät luokkaan, eivät yksittäiseen olioon n Kaikki ko. luokan oliot voivat käyttää

Lisätiedot

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit IDL - proseduurit 25. huhtikuuta 2017 Viimeksi käsiteltiin IDL:n interaktiivista käyttöä, mutta tämä on hyvin kömpelöä monimutkaisempia asioita tehtäessä. IDL:llä on mahdollista tehdä ns. proseduuri-tiedostoja,

Lisätiedot

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin.

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin. 2. Ohjausrakenteet Ohjausrakenteiden avulla ohjataan ohjelman suoritusta. peräkkäisyys valinta toisto Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 4 vastaukset Harjoituksen aiheena ovat imperatiivisten kielten lauseisiin, lausekkeisiin ja aliohjelmiin liittyvät kysymykset. Tehtävä 1. Mitä

Lisätiedot

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014 18. syyskuuta 2014 IDL - proseduurit Viimeksi käsiteltiin IDL:n interaktiivista käyttöä, mutta tämä on hyvin kömpelöä monimutkaisempia asioita tehtäessä. IDL:llä on mahdollista tehdä ns. proseduuri-tiedostoja,

Lisätiedot

Apuja ohjelmointiin» Yleisiä virheitä

Apuja ohjelmointiin» Yleisiä virheitä Apuja ohjelmointiin» Yleisiä virheitä Ohjelmaa kirjoittaessasi saattaa Visual Studio ilmoittaa monenlaisista virheistä "punakynällä". Usein tämä johtuu vain siitä, että virheitä näytetään vaikket olisi

Lisätiedot