PLA-32100 OLIO-OHJELMOINTI Object programming versio: 15.1.2015 Mika.saari@tut.fi 1
Kurssin suoritus Kummastakin tentistä saa enintään 10 pistettä. Harjoituksista enintään 10 pistettä. Eli kurssin maksimipistemäärä on 30. Arvosana määräytyy oheisen taulukon mukaan. Tenttiohjelman arviointikriteerit ovat: toimii 2, tekee annetun tehtävän 3, ratkaisutapa 3 ja luettavuus 2. Harjoituksia on 20 ja niillä on eräpäivät. Opiskelija lähettää harjoitusten vastaukset sähköpostin liitteenä osoitteeseen mika.saari@tut.fi. Harjoitus- ja tenttipisteet huomioidaan vain vuoden 2015 aikana. Kurssista on kaksi uusintatenttiä (5.6 ja 11.9), joilla voi korottaa heikoimman tentin arvosanaa. Luentoesitys ja luennolla rakennetut ohjelmat löytyvät osoitteesta www.students.tut.fi/~saari5/pla_32100_2015/esimerkit Harjoitusten mallivastaukset löytyvät osoitteesta www.students.tut.fi/~saari5/pla_32100_2015/ratkaisut/ eräpäivän jälkeen. Kurssimateriaalina käytetään kirjaa Vesterholm-Kyppö: Javaohjelmointi (joka oletetaan opiskelijalla olevan käytettävissään) PISTEET ARVOSANA 27 5 24 4 21 3 18 2 15 1 <15 0 Mika.saari@tut.fi 3
Kurssin kirjoja Mika Vesterholm, Jorma Kyppö: Java-ohjelmointi, Talentum 2008 Simo Silander, Vesa Ollikainen, Juha Peltomäki, : Java, Docendo 2010 Kai Koskimies: Oliokirja Verkkoaineistot The Java Tutorials http://docs.oracle.com/javase/tutorial/index.html Mika.saari@tut.fi 4
Kurssin sisältö Javan oliomallin perusominaisuudet 3 luentoa 3-5 viikot Graafinen käyttöliittymä 2 6-7 Poikkeusten käsittely 1 8 Tiedostot 1 11 (Oliosuunnittelu: UML 0) Tietokantaliittymä 2 12-13 (Säikeet 0) (Geneerisyys 0) Dokumentointi, versionhallinta 1 14 Kertaus 2 16-17 JPA Oliokannat Muut olioparadigmat Mika.saari@tut.fi 5
Miksi luokkia? EDUT Suurten ohjelmistojen rakentaminen (mallintaminen, työnjako, koodin ryhmittely ) Koodin uudelleenkäyttö (luokkahierarkia, rajapinta, geneerisyys, oliot) Muutosten rajaaminen (projektit, paketit, luokat) PERUSOMINAISUUDET Kapselointi Periyttäminen Monimuotoisuus Mika.saari@tut.fi 6
Luokkatyyppejä Sovellusluokat Tekniset luokat Suoritettava luokka Luokkakirjasto Konkreettinen luokka Abstrakti luokka Ilmiö luokka MITEN LÖYDÄN LUOKAT? Toimintakuvauksen substantiivit ja tapahtumat, joista talletetaan tietoa. Miksa 7
Luokka ja olio Luokka Luokan data Luokan metodit Olion data Olion data Olion data Olion metodit Olion metodit Olion metodit new-lauseella luodaan olioita class Asiakas { static int kpl; String nimi; Luokka static int montako( ) { return kpl; String annanimi() { return nimi; Oliot Mika.saari@tut.fi 8
KAPSELOI tieto ja toiminta private private public ROCK Opiskelija opno jäsenmaksu tarkista annanro Rekisteröinti uusiopiskelija op Suoritus päivitä lisääop kirjaatentti Mika.saari@tut.fi 9
Koodin sijoittelu Sovellus Projekti Pakkaus (hakemisto) Käännösyksikkö (tiedosto) Luokka Metodi Make 10
Koodin sijainti metodi ja luokka public class Opiskelija { // Dataa mutta ei koodia public void annanro() { // Dataa ja koodia public static int main() { Käännösyksikkö (tiedosto) class Opiskelija { public void annanro() { public class Opettaja { public void tarkastatentti() { projekti pakkaus (hakemisto) package hakemistopolku public class Opiskelija { public void annanro() {. package hakemistopolku public class Opettaja { public void tarkastatentti() { Make 11
Käännösyksikkö (compilation unit) Käännösyksikössä (java-tiedostossa) on vain yksi public-luokka, jonka nimi on tiedoston nimi Käännösyksikön (java-tiedosto) kukin luokka kääntyy omaksi class-loppuiseksi tiedostokseen Käännösyksikön alussa package-määre ilmoittaa, mihin projektin koodihakemiston (src) alihakemistoon kooditiedostot tallennetaan Käännösyksikön käännetyt tiedostot (class-loppuiset) tallentuvat annetun hakemiston (bin) package-määreen mukaiseen alihakemistoon Jos ei package-määrettä, tiedostot tallennetaan nyky- eli oletushakemistoon (default package) Jotkin editorit saattavat vaatia class-tiedoston lisäksi java-loppuisen tiedoston olemassaolon Make 12
Pakkaus (package) A package is a collection of related classes and interfaces providing access protection and namespace management. Pakkaukset muodostavat hierarkkisen rakenteen (hakemistohierarkia) Pakkaukset otetaan käyttöön käännösyksikön alussa olevilla import-lauseilla Import lauseessa hierarkkisesti määritetään pakkaushakemiston taso Alipakkaukset tarvitsee tuoda omalla import-lauseellaan Pakkauksesta voi ottaa nimetyn luokan tai kaikki luokat (*) Pakkauksessa ei saa olla saman nimisiä luokkia Luokkaa haetaan import- tai oletuspakkauksista Pakkausta haetaan CLASSPATH-poluista Koodi tallennetaan lähdekoodihakemiston package-määreen nimiseen alihakemistoon (pakkaukseen) Oletuspakkauksia ovat käännösyksikön pakkaus ja java.lang-pakkaus (String ja System luokat), jotka eivät tarvitse import-lausetta Oletuspaketista voidaan viitata toiseen oletuspakettiin ilman import- lausetta! (classpath-polku oltava kunnossa.) Make 13
Esimerkki: koodin sijainti Ryhma.java package pori.tty; import java.swing.*; import java.util.arrays; import omat.jutut.*; //classpath:sta eteenpäin class Opiskelija {. public class Ryhma { //yksi public luokka tiedostossa Make 14
Luokasta olioita public class Opiskelija { private String opno; private String nimi; // luokkamuuttujia // alustettuja public void annanro() { // olio on tietue jos ei metodeita public class Luokka { public static void main(string[ ] args) { Opiskelija uusi = new Opiskelija(); uusi.annanro(); uusi.nimi= Timo Teekkari ; // Virhe: ei suoraan ominaisuuteen Make 15
Laadi Pankkitili-luokka. Luentoharjoitus 1 Luokkien välinen kutsu ja luokkatason data Luokassa on otto- ja pano-metodit. Kansion toisessa tiedostossa on main-metodi, joka antaa käyttäjän valita toiminnon ja sen perusteella kutsuu pankkitili-luokan metodeja. Täydennä pankkitililuokkaa sisäänkirjoittautumissekä uloskirjautumismetodilla. Jos käyttäjä ei osaa antaa oikeaa salasanaa ei otto- eikä pano-metodit toimi. Make 16
PERIYTÄ luokkahierarkiassa Yläluokat kuvaavat yleisiä käsitteitä, joissa kuvataan perustiedot ja yleiset toiminnot Yläluokista periytetään aliluokkia (johdettuja luokkia), jotka perivät yläluokan tiedot ja toiminnot Aliluokka voi lisätä uusia tietoja ja toimintoja (tarkentaa yläluokkaa) korvata yläluokan tietoja ja toimintoja (kuormittaminen) kehittää yläluokan palveluja (nostaa abstraktiotasoa) Näin muodostuu luokkien hierarkia (vrt. käsitehierarkia), joka helpottaa ohjelmien muuttamista ja säästytään samojen asioiden moninkertaiselta koodaamiselta Luokat, metodit ja tiedot ovat virtuaalisia eli periytyvät, mikäli ei erikseen estetä (final, private) Ei moniperiytyvyyttä, mutta voi toteuttaa useita rajapintaluokkia Make 17
Luokkahierarkiaesimerkki Luokka Olio Opiskelija muuta() nimi nro Amk Matti Oja Akateeminen muuta() 196054 suunnitelma() valmistumisvuosi maksa() maksettu Pia Mäki Kari Elo muuta() 1234 muuta() 1399 suunnitelma() 2013 suunnitelma() 2012 Make 18
Muuttujan näkyvyysmääreet Näkyvyysmääre private 4 protected ei mitään public Sama luokka kyllä kyllä kyllä kyllä Näkyvyysalue Luokan jälkeläinen Pakkauksen luokissa ei kyllä 1 ei 3 kyllä ei ei 2 kyllä kyllä Kaikkialla ei ei ei kyllä 1. Viitteen oltava viittaavan luokan tyyppiä 2. Virheellisesti näkyy pakkauksessa 3. Näkyy samassa pakkauksessa 4. Private muuttujaan saantimetodit (set/get, accessor) Make 19
Muuttujan näkyvyys public class Opiskelija { // alustuu automaatt. public String nimi; // kaikkialla String ohjelma= Tite ; // hakemistossa static final int TUTKINTO=180;// luokan olioista protected int aloitusvuosi;// aliluokissa private String opno; // luokassa public double keskiarvo(int kpl) {// ei alkuarvoa double ovt = 0; // metodissa for(int i=0; i<kpl; i++) // lohkossa ovt += nro[i]; return ovt maailma pakkaus luokka aliluokka olio metodi lohko Make 20
Metodin näkyvyys public class Akateeminen extends Opiskelija { static int nro() { // käyttää staattisia muuttujia ja metodeita public String nimi() { private boolean opintotuki( ) { protected void maksu() { // jos ei määrettä, näkyy pakkauksessa Make 21
Luokan näkyvyys public luokka ei määrettä final luokka abstract luokka interface luokka // käytettävissä ulkopuolelta // käytettävissä paketissa // ei aliluokkia // osa/kaikki implementoinnit aliluokissa // (rajapinta, liittymä) // kaikki implementoinnit toteuttavassa // luokassa 22
Kuormittaminen, korvaaminen, peittäminen Samassa luokassa metodi voidaan (yli)kuormittaa samannimisellä metodilla kunhan vain parametrit ovat määrältään tai tyypiltään erilaiset Aliluokassa metodi voidaan korvata samannimisellä metodilla kunhan sekä paluuarvo että parametrit täsmäävät Kenttä tai metodi voidaan peittää luokkahierarkian alimmilta tasoilta määrittelemällä se private-tyyppiseksi Miksa 23
Esimerkki: näkyvyydet class Koululainen { double summa, keskiarvo; int kpl; String opiskelijatunnus = "Olli Oppivainen"; public void arvosana(double numero){ summa += numero; kpl++; keskiarvo = summa/kpl; class Perusopiskelija extends Koululainen { int opiskelijatunnus; double opintopisteet; public void kirjaus () { ++opiskelijatunnus; public void suoritus (double viikot) { opintopisteet += 1.5*viikot; public void suoritus (int pisteet){ opintopisteet += pisteet; class Jatko_opiskelija extends Perusopiskelija { public void tulosta () { System.out.println (opiskelijatunnus); System.out.println (opintopisteet); System.out.println (keskiarvo); public void suoritus (double ov) { opintopisteet += 1.2*ov; public class Opiskelijasovellus { public static void main (String[] args) { Jatko_opiskelija opp = new Jatko_opiskelija(); opp.kirjaus(); opp.arvosana(3.5); opp.suoritus(2.5); opp.arvosana(4); opp.suoritus(3); opp.tulosta(); Metodi suoritus kuormitettu ja korvattu. Muuttuja opiskelijatunnus peitetty. Mitä tulostuu? Mikä toteutuksessa huonoa? (korjataan Make harjoituksessa 24 2)
Kirjasto Luokassa final luokka // estää aliluokat private konstruktori // estää olion luonnin public metodeja // tarjottavat palvelut static metodit // ei tarvita kopioita static muuttujat // ei tarvita kopioita Make 25
KONSTRUKTORI Konstruktori (rakentaja) on luokan metodi, joka halutaan suorittaa olion synnyn yhteydessä (tarkkaan ottaen konstruktori ei ole luokan metodi, koska ei periydy) Konstruktorikoodilla on sama nimi kuin luokalla Konstruktorilla ei ole paluuarvoa Oletuskonstruktori Luodaan automaattisesti Ei tee mitään Parametriton Ei yleensä tarvitse kirjoittaa Tarvitsee kirjoittaa jos kirjoitetaan omakin konstruktori Esim. Opiskelija(){ Javassa ei ole destruktoria (roskien keruu finalize) Make 26
Konstruktoriesimerkki public class Luokka { public static void main(string[ ] args) { Opiskelija uusi = new Opiskelija( 178123, 60); public class Opiskelija{ private String opno; private double ov; // luokkamuuttujia public Opiskelija(String opno, double hyvitys) { this.opno=opno; ov=hyvitys; Make 27
this, super, this(), super() this-sanalla viitataan olioon, jonka sisällä ollaan this viittaa myös luokan toiseen konstruktoriin super-sana viittaa isään super viittaa myös isän konstruktoriin Jos konstruktorissa halutaan suorittaa toinen konstruktori on se tapahduttava konstruktorin ensimmäisenä lauseena Make 28
Konstruktorin kuormittaminen public class Opiskelija{ private String opno; // luokkamuuttujia private double ov; public Opiskelija(String opno){ this.opno=opno; public Opiskelija(String opno, double hyvitys) { this(opno); ov=hyvitys; public Opiskelija(){ // parametriton olio Make 29
Konstruktorien kutsujärjestys public class Opiskelija { private String opno; private double ov; public Opiskelija (String opno, double hyvitys) { this(opno); ov = hyvitys; public class Lasnaoleva extends Opiskelija { static private int nextopno; private int vuosi; public Lasnaoleva () { opno = nextopno++; System.out.println( Tervetuloa +opno); public Opiskelija (String opno){ this.opno = opno; public void kirjaus (int aika) { vuosi = aika; public Opiskelija(){ Korjaa esimerkin virheet! // Välttämätön missä tilanteessa? 1. new varaa luokille muistin ja alustaa luokkien muuttujat tyyppinsä alkuarvoihin 2. alustetaan Opiskelija-luokan muuttujat annettuihin alkuarvoihinsa 3. suoritetaan Opiskelija-konstruktori 4. alustetaan Lasnaoleva-luokan muuttujat annettuihin alkuarvoihinsa 5. suoritetaan Lasnaoleva-konstruktori Make 30
Luentoharjoitus 2 Parametroidut oliot ja konstruktori Laadi monisteen Jatko_opiskelija-, Perusopiskelija- ja Koululainen luokille järkevät kentät näkyvyysmääreineen. Lisäksi laadi konstruktorit, jolla alustat kentät. Luo samassa luokassa olevalla main-metodilla kaksi opiskelijaa ja tulosta opiskelijoiden tiedot. Make 31
MONIMUOTOISUUS polymorfismi Dynaaminen viittaus Abstrakti yliluokka Aliluokka Aliluokka täydentää abstraktin luokan puuttuvat osat Sovellus Rajapintaluokka A Yliluokka Rajapinta- Aliluokka Aliluokka lisää yliluokkaan tietoja tai metodeja luokka B Make 32
Dynaaminen viittaus public class Opiskelija { protected String nimi; public class Akateeminen extends Opiskelija { private int ov; public Opiskelija(){ public Opiskelija (String nimi) { this.nimi = nimi; public void annanimi (String opnimi) { nimi = opnimi; public void tulosta() { System.out.print(nimi); Mitä tulostuu? // Suorittaa Opiskelija()-konstruktorin public Akateeminen (int hyvitys, String nimi) { ov = hyvitys; this.nimi = nimi; //annanimi (nimi); public void tulosta() { // Olisiko tämä parempi? System.out.print(nimi+ov); // Miten korjataan // jos nimi private? Opiskelija ins = new Opiskelija ( Kalle Hovi ); Akateeminen di = new Akateeminen (60, Matti Mäki ); ins.tulosta(); di.tulosta(); ins = di; ins.tulosta(); Make 33
Abstrakti luokka Abstrakti luokka määrittelee korkean tason käsitteen, jonka toiminnot on (täysin) määritelty, mutta ei välttämättä toteutettu Abstrakti luokka siis antaa kutsujalle (täydellisen) kuvan käsitteestä ja mahdollistaa sen käytön ennen kuin kaikki varsinaiset implementaatiot on tehty (mahdollistaa siis ajan mukaan tapahtuvan käsitteiden kehittelyn ja säästää perusasioiden uudelleen koodaamiselta) Abstraktista luokasta periytyvän aliluokan pitää toteuttaa kaikki isänsä ei-toteutetut metodit (lupaus kutsujalle) Aliluokka perii ja voi syrjäyttää abstraktin isänsä metodit ja muuttujat Aliluokka luonnollisesti voi lisätä uusia muuttujia ja metodeja Abstraktista luokasta ei voi luoda ilmentymiä (olioita) Luokka ja abstraktit metodit merkitään sanalla abstract Make 34
Abstrakti luokka - esimerkki abstract class AbstractOpiskelija { private String etunimi; private String sukunimi; public AbstractOpiskelija(String enimi, String snimi){ etunimi = enimi; sukunimi = snimi; public String nimi(){ return etunimi+" "+sukunimi; class Opiskelija extends AbstractOpiskelija{ private double[] arvosanat; public Opiskelija(String enimi, String snimi, double[] ov){ super (enimi, snimi); arvosanat = ov; public double keskiarvo(){ double summa=0; int kpl=0; abstract double keskiarvo(); public class AbstraktiEsimerkki{ public static void main(string[] args){ double[] tulokset = {1, 2.5, 0, 4, 5; for (int i=0; i<arvosanat.length; i++){ if (arvosanat[i]>0){ summa += arvosanat[i]; kpl++; return summa/kpl; AbstractOpiskelija di = new Opiskelija("Kalle","Koivu,tulokset); System.out.println(di); public String tostring(){ return nimi()+" "+keskiarvo(); Make 35
Rajapintaluokka (käyttöliittymä, interface) Rajapintaluokka on täysin abstrakti eli ei lainkaan koodia -pelkkiä metodimäärittelyjä Luokassa pitää olla toteutukset kaikille käyttämänsä rajapinnan metodeille Luokka voi toteuttaa useita rajapintoja Rajapinta voi toteuttaa toisia rajapintoja Jos määritellään muuttujia tulee niistä luokan vakioita (static final) Abstrakti luokka on olion abstraktio, rajapintaa voidaan pitää palvelujen mallina Make 36
Rajapintaluokka esimerkki interface Opintotoimisto{ public void annaarvosana(int kurssi, double numero); public void tulostaarvosanat(); public String tostring(); interface Suoritukset{ public void tulostaarvosanat(); abstract class AbstractOpiskelija { private String etunimi; private String sukunimi; public AbstractOpiskelija(enimi, snimi){ etunimi = enimi; sukunimi = snimi; public String nimi(){ return etunimi+" "+sukunimi; abstract double keskiarvo(); public class ImplementsEsimerkki{ public static void main(string[] args){ double[] tulokset = {1, 2.5, 0, 4, 5; Opintotoimisto di = new Opiskelija("Kalle", "Koivu", tulokset); di.tulostaarvosanat(); di.annaarvosana(3, 4); di.tulostaarvosanat(); class Opiskelija extends AbstractOpiskelija implements Opintotoimisto, Suoritukset{ private double[] arvosanat; public Opiskelija(String enimi, String snimi, double[] ov){ super (enimi, snimi); arvosanat = ov; public void annaarvosana(int kurssi, double numero){ arvosanat[kurssi-1] = numero; public void tulostaarvosanat(){ System.out.println(toString()); for (int i=0; i<arvosanat.length; i++) System.out.println(arvosanat[i]); public double keskiarvo(){ double summa=0; int kpl=0; for (int i=0; i<arvosanat.length; i++){ if (arvosanat[i]>0){ summa += arvosanat[i]; kpl++; return summa/kpl; public String tostring(){ return nimi()+" keskiarvo= "+keskiarvo(); Make 37
Geneerisyys Viitetyyppejä (olioita) voidaan korvata geneerisellä muuttujalla Geneerinen määritys: ArrayList <E> (); Tyypittäminen olioilla: new ArrayList <Asiakas> (); Perustietotyyppejä ei voida korvata geneerisellä muuttujalla Parametrina on tapana käyttää isoa kirjainta T (tyyppi), E (elementti), Geneerinen metodi Geneerinen luokka Geneerinen rajapinta MetodinKuormitus.java MetodiGeneerinen.java GeneerinenArray.java GeneerinenRajapinta.java Make 38
Geneerisyys ArrayList<Asiakas> lista = new ArrayList<>(); public interface Pino <E> { public void laita(e olio); public E ota(); public class RajattuPino <E> implements Pino <E> { private koko; private E[ ] oliot = (E[ ]) new Object[10]; public void laita (E olio) { oliot[koko++]= olio; public E ota() { return oliot[--koko]; Sovellus Pino <Asiakas> luettelo = new RajattuPino <>(); Sovellus public static <T> void laitapinoon(t olio, Pino<T> pino){ pino.laita(olio); Make 39
OLIOIDEN KÄYTTÖTILANTEITA Make 40
Olioita kokoelmassa public class Oliotaulukko { public static void main(string[] args) { Henkilo[] tekijät = new Henkilo[5]; tekijät[0] = new Henkilo("Liisa", 2000); tekijät[1] = new Henkilo("Teija", 3000); tekijät[2] = new Henkilo("Kalle", 1500); tekijät[3] = new Henkilo("Risto", 1900); tekijät[4] = new Henkilo("Marko", 1800); int summa = 0; for (Henkilo ihminen: tekijät) { summa += ihminen.annapalkka(); System.out.println(ihminen); System.out.println("\nPalkkasumma "+summa); class Henkilo { static int id=100; private int hlonro; private String nimi; private double palkka; Henkilo (String nimi, double rahaa){ this.nimi = nimi; palkka = rahaa; hlonro = id++; public double annapalkka(){ return palkka; public String tostring(){ return hlonro+": "+nimi; Make 41
Olioita parametrina public class Olioparametri { public static void main(string[] args) { Henkilo1[] tekijät = new Henkilo1[5]; tekijät[0] = new Henkilo1("Liisa", 2000); tekijät[1] = new Henkilo1("Teija", 3000); tekijät[2] = new Henkilo1("Kalle", 1500); tekijät[3] = new Henkilo1("Risto", 1900); tekijät[4] = new Henkilo1("Marko", 1800); int summa = 0; for (Henkilo1 ihminen: tekijät) tulosta (ihminen); private static void tulosta(henkilo1 henkilo){ System.out.println(henkilo); class Henkilo1 { static int id=100; private int hlonro; private String nimi; private double palkka; Henkilo1 (String nimi, double rahaa){ this.nimi = nimi; palkka = rahaa; hlonro = id++; public String tostring(){ return hlonro+": "+nimi+" "+palkka; Make 42
Olion tulostaminen Tulostettaessa olio tulostaa tostring()-metodin palauttama arvon Yleensä Object-luokan tostring() palauttama arvo ei ole riittävä, vaan olioon kannattaa ohjelmoida oma tostring()-metodi Samoin toimivat rajapintamekanismin callback-metodit (käyttöliittymissä, lajittelussa, ) palvelu Palvelu p= new Palvelu(); p.laske(this); public void kaava(){... public laske(object a){... a.kaava();... Make 43
Olioiden vertailu Make 44
Olioiden vertailu Make 45
Olio-ohjelmointi ohjeita 1. Kaunis ohjelma 2. Ensin toimimaan, sitten nopeuta 3. Hajota ja hallitse (olioita) 4. Palveluluokka / käyttäjäluokka (sovellus) 5. Luokan nimet itsedokumentoivia 6. Luokka hoitaa yhden selkeän käsitteen 7. Suunnittelu tuottaa luokat, liittymät, suhteet 8. Johdettu luokka yksinkertaistaa ennemmin kuin laajenta 9. Kätke monimutkaisuus luokan käyttäjältä (ohjelmoija) 10. Toistuva koodi metodiksi (bottomup-suunnittelu) Make 46
Olio-ohjelmointi ohjeita 11. Parametrilistan pitäisi olla lyhyt 12. Aloita yksinkertaisella luokalla 13. Luo testikoodi ennen luokan koodia? 14. Jätä luokkaan testimetodit (main) 15. Korvaa switch ja tyypintutkinta (instanceof) ylimäärittelyllä ja monimuotoisuudella 16. Käytä poikkeushierarkiaa odottamattomille tilanteille (ei harvinaisille) 17. Sun coding conventions java.sun.com/docs/codeconv/index.html 18. Älä käytä unkarilaista nimiöintitapaa (ilaskunumero) 19. Metodi lyhyt ja hoitaa yhden tehtävän 20. Pidä asiat private Make 47
Olio-ohjelmointi ohjeita 21. Korvaa vakiot symbolisilla vakioilla 22. Konstruktorissa aseta olio kuntoon; vältä kutsumasta metodeita Make 48
Luentoharjoitus 3 Modularisointi Lottopelissä pelaaja syöttää useita rivejä lottonumeroita. Sen jälkeen arvotaan oikea rivi. Lopuksi tarkistetaan kuinka pelaajaa onnisti. Suunnittele lottopeliin merkkipohjainen ja graafinen käyttöliittymä. Sijoita lottopelin pelitoiminnot eri luokkaan siten, että molemmat käyttöliittymät voivat käyttää sitä. Minkälainen rajapinta luokkien välille pitäisi määritellä? Make 49
-Vastaus 3 Lottoristikko Lottonumero t Syötä rivi Arvo Tarkasta Talleta rivi Arvo rivi 1 Syötä numerot 2 Arvo oikeat numerot 3 Tarkasta tulos Tarkasta Make 50
Luentoharjoitus 4 Olioita taulukossa Laadi autokauppa, joka hallitsee annettua määrää autoja. Kauppaan voidaan lisätä ja poistaa uusia autoja, laskea kaupan autojen keskihinta, listata kalliit (yli keskihintaiset) autot ja etsiä autoja värin mukaan. Make 51
Luentoharjoitus 5 Periytyminen ja monimuotoisuus Alla oleva Lainaus sovellus käyttää Kirja ja Lainakirja luokkia. Kirjoita Kirja ja Lainakirja luokat. import java.util.*; public class Lainaus { public static void main(string[] args) { ArrayList lainassa = new ArrayList(); // add-metodin parametrit ovat teoksen tekijä, nimi ja eräpäivä lainassa.add(new Kirja("Vesterholm", "Java-ohjelmointi")); lainassa.add(new Kirja("Lafore", "Data Structures")); lainassa.add(new Kirja("Haikala", "Käyttöjärjestelmät")); lainassa.add(new Lainakirja("Disney", "Aku Ankan vuosikirja 2007", "21.6.2007")); lainassa.add(new Lainakirja("Lordi", "Hard Rock Hallelujah", "31.5.2007" )); lainassa.add(new Lainakirja("Vesterlund", "Jääkiekon pelitaktiikat", "15.5.2007")); // tulostaa olioiden kaikki tietokentät for (Object teos: lainassa) ((Kirja)teos).tulosta(); Make 52
Luentoharjoitus 6 Abstraktisuus ja rajapinta Kirjoita alla olevan koodin luokat Pankkitili, Asunto ja Sijoitus a. jos Sijoitus on rajapinta luokka b. jos Sijoitus on abstrakti luokka Make 53
SWING KÄYTTÖLIITTYMÄ I don t mean a thing if it ain t got that swing http://docs.oracle.com/javase/tutorial/uiswing/index.html OtaTaiJata.java Make 55
GRAAFISET KOMPONENTIT Make 56
Perusnäyttö JFrame JMenuBarJMenu JMenu ContentPane JToolbar JButton JButton JSplitPane JScrollPane JList JPanel JPanel JLabel JPanel JScrollPane JEditorPane JLabel Make 57
Swing komponentteja JComponent AbstractButton JButton JMenuItem JCheckBoxMenuItem JMenu JRadioButtonMenuItem JToggleButton JCheckBox JRadioButton JTextComponent JTextArea JEditorPane JTextPane JTextField JFormattedTextField JPasswordField JComboBox JLabel JList JPopupMenu JProgressBar JScrollBar JSeparator JSlider JSpinner JTable JToolTip JTree JFileChooser JColorChooser JOptionPane JPanel JScrollPane JSplitPane JTabbedPane JMenuBar JToolBar JFrame JDialog JApplet JInternalFrame JRootPane JLayerPane JDesktopPane Katso tutorial-sivu verkosta: docs.oracle.com/javase/tutorial/uiswing/index.html SwingComponents.java ja SwingSet3.jnlp Make 58
Perusikkuna import javax.swing.*; import java.awt.*; public class Perusikkuna extends JFrame { JLabel selite; public Perusikkuna() { settitle("tervehdysikkuna"); selite = new JLabel("Terve"); add(selite); setdefaultcloseoperation(jframe.exit_on_close); public static void main(string[] args) { Perusikkuna ikkuna = new Perusikkuna(); ikkuna.setsize(200,100); // voisi olla Perusikkuna-konstruktorissa ikkuna.setvisible(true); Perusikkuna.java Make 59
Asettelijat Asettelijat.java Make 60
Layout-ikkuna import javax.swing.*; import java.awt.*; public class Layoutikkuna extends JFrame { JLabel selite; public Layoutikkuna() { settitle("tervehdysikkuna"); selite = new JLabel("Terve"); // BorderLayout sisältöpanelin oletusasettelija // setlayout(new BorderLayout()); add(selite, BorderLayout.EAST); // getcontentpane().add(selite, BorderLayout.EAST); setdefaultcloseoperation(jframe.exit_on_close); public static void main(string[] args) { Layoutikkuna ikkuna = new Layoutikkuna(); ikkuna.setsize(200,100); ikkuna.setvisible(true); Layoutikkuna.java Make 61
SpringLayout jdk1.4 Komponenttien suunta ja välit määritellään. 20 20 20 20 20 50 http://java.sun.com/docs/books/tutorial/uiswing/layout/spring.html SpringAsettelu.java Make 62
GroupLayout jdk1.6 Komponenttien ryhmät vaaka ja pystysuunnassa määritellään (myös välit). Vaakaryhmät Pystyryhmät GroupAsettelu.java http://java.sun.com/docs/books/tutorial/uiswing/layout/group.html Make 63
TAPAHTUMIEN KÄSITTELY Make 64
Kuuntelija Kuuntelijaksi ilmoittautuminen ja tapahtuman vastaanotto (AWTn event delegation model) jvm / WindowListener sovellus Komponentti addwindowlistener() tapahtumien postituslista käyttöjärjestelmä windowclosing() metodi EventObject Close Make 65
Ikkunan kuuntelija Jokainen olio, joka haluaa ottaa vastaan tietyn tapahtuman, ilmoittautuu ko. tapahtuman kuuntelijaksi addwindowlistener(new Kuuntelija()) ja toteuttavat liittymän vaatimat metodit, jotka reagoivat tapahtumaan suorittamalla käyttäjän haluamat toimenpiteet, esimerkiksi windowclosing(). Make 66
Kuuntelija vai adapteri Koska kuuntelijaksi kirjautuvan sovelluksen pitää toteuttaa kaikki rajapinnan metodit, tarvitsee laatia metodit myös tapahtumille, joista sovellusohjelmassa ei olla kiinnostuneita. Tämän helpottamiseksi on laadittu Adapterikuuntelijaluokat, jossa on tyhjät metodit kaikille pakollisille rajapintametodeille, joten sinun pitää ylikuormittaa sovelluksessa vain tarvitsemasi metodit. Make 67
Esimerkki (kuuntelija) Kuuntelija ulkoisena luokkana import java.awt.event.*; Import java.awt.*; import javax.swing.*; public class Kuuntelijatesti1 extends JFrame{ public static void main(string[] args){ Kuuntelijatesti1 testi = new Kuuntelijatesti1(); testi.setvisible(true); public Kuuntelijatesti1 (){ addwindowlistener(new Kuuntelija()); // Kuuntelija ulkoisena luokkana class Kuuntelija implements WindowListener{ public void windowclosing(windowevent e){ System.exit(0); public void windowactivated(windowevent e){ public void windowclosed(windowevent e){ public void windowdeactivated(windowevent e){ public void windowdeiconified(windowevent e){ public void windowiconified(windowevent e){ public void windowopened(windowevent e){ import java.awt.event.*; Import java.awt.*; import javax.swing.*; public class Kuuntelijatesti2 extends JFrame{ public static void main(string[] args){ Kuuntelijatesti2 testi = new Kuuntelijatesti2(); testi.setvisible(true); public Kuuntelijatesti2 (){ addwindowlistener(new Kuuntelija()); Kuuntelija sisäluokkana // Kuuntelija sisäluokkana class Kuuntelija implements WindowListener{ public void windowclosing(windowevent e){ System.exit(0); public void windowactivated(windowevent e){ public void windowclosed(windowevent e){ public void windowdeactivated(windowevent e){ public void windowdeiconified(windowevent e){ public void windowiconified(windowevent e){ public void windowopened(windowevent e){ Make 68
Esimerkki (adapteri) Kuuntelijan laajentaminen adapteriluokasta public class Adapteritesti1 extends JFrame{ public static void main(string[] args){ Adapteritesti1 testi = new Adapteritesti1(); testi.show(); Kuuntelija nimettömänä sisäluokkana public class Adapteritesti2 extends JFrame{ public static void main(string[] args){ Adapteritesti2 testi = new Adapteritesti2(); testi.show(); public Adapteritesti1 (){ addwindowlistener(new Kuuntelija()); class Kuuntelija extends WindowAdapter{ public void windowclosing(windowevent e){ System.exit(0); public Adapteritesti2 (){ addwindowlistener(new WindowAdapter() { public void windowclosing(windowevent e) { System.exit(0); ); Make 69
Kuuntelijarajapintoja ja niiden metodeja WindowListener WindowAdapter windowopen windowclosing windowsclosed windowactivated windowdeactivated windowiconified windowdeiconified Ikkunan avaamisesta, sulkemisesta, aktivoimisesta syntyvät tapahtumat Kuuntelijatesti2.java Adapteritesti2.java ActionListener actionperformed Komponentin tapahtumat AjanArviointi.java FocusListener FocusAdapter focusgained focuslost Komponentti saa tai menettää fokuksen KeyListener KeyAdapter keytyped keypressed keyreleased Näppäimistön näppäimen painamiseen liittyvät tapahtumat MouseListener mouseclicked mousepressed mousereleased mouseentered mouseexited Tapahtuvat hiirellä klikattaessa, painettaessa nappi pohjaan, vapautettaessa, tullessa komponentin päälle ja poistuttaessa MouseMotionListener MouseMotionAdapter mousedragged mousemoved Hiirtä vedetään nappi pohjassa tai liikutetaan MouseAdapter MouseListener MouseMotionListener MouseWheelListener Hiiri.java http://download.oracle.com/javase/tutorial/uiswing/index.html JDK-help java.awt.event Make 70
MVC-arkkitehtuuri Osat Malli huolehtii järjestelmän sovellusaluekohtaisen tiedon tallentamisesta, ylläpidosta ja käsittelystä. Näkymä määrittää käyttöliittymän ulkoasun ja mallin tietojen esitystavan käyttöliittymässä. Ohjain eli kontrolleri vastaanottaa käyttäjältä tulevat käskyt sekä muuttaa mallia ja näkymää vastauksena niihin. Etuja Malli ei riipu näkymästä eikä ohjaimesta. Malli voidaan suunnitella, ohjelmoida ja testata riippumatta järjestelmän muista osista. Samaan malliin voidaan tehdä erilaisia käyttöliittymiä. Saman järjestelmän tietoon voi olla pääsy esimerkiksi merkki-, graafisella ja webbikäyttöliittymällä. Näkymän ja ohjaimen toimintaan voidaan tehdä muutoksia muuttamatta mallia. Näkymän ja ohjaimen riippuvuus toisistaan on verrattain pieni. Käyttöliittymän ulkoasu eli näkymä on mahdollista vaihtaa muuttamatta ohjainta. Ohjainta voidaan muuttaa muuttamatta näkymää. Käyttöliittymän asynkronointi on helppoa. Myös muita monitasomalleja. Make 71
Loton MVC-esimerkki NÄKYMÄ (VIEW) OHJAIN (CONTROL) MALLI (MODEL) interface luo näkymäolio luo malliolio Rekisteröi viite ohjaimeen arvo tarkista tyhjennä Make 72
Luentoharjoitus 7 Tee rahanvaihtosovellus, jolla voit laskea antamasi euromäärän dollareina ja päinvastoin. Make 74
Luentoharjoitus 8 Suunnittele GUI-editorilla sovellus, joka laskee kahden kentän arvon yhteen ja pistää tuloksen kolmanteen kenttään. Make 75
Luentoharjoitus 9 Laadi alla olevan näköinen näyttö, jolla lisäät puhelinluetteloon nimi- ja numerotietoja. Lisää-nappi lisää näyttöön syötetyt tiedot luetteloon. Edellinen-nappi näyttää edellisen numeron luettelosta. Seuraava-nappi näyttää seuraavan numeron luettelosta. Poista-nappi poistaa seuraava- ja edellinen-napeilla haetun nimi- ja numerotiedon luettelosta. Näyttö pitää koodata käsin eli koodia ei saa generoida graafisella näytönsuunnitteluvälineellä. Make 76
Luentoharjoitus 10 Ohjelmoi graafinen nelilaskin. Make 77
POIKKEUSKÄSITTELY Lesson: Exceptions (The Java Tutorials > Essential Classes) Make 81
Virheistä Ennen hoidettiin paluuarvolla, nykyisin poikkeuksilla Käännösaikaiset virheet Editorin löytämät syntaksivirheet Ajoaikaiset virheet virhetilanne ympäristössä: muisti loppu, tietoväline rikki tietovirtavirheet taulukon rajojen ylitys nollalla jako null-viitteet ohjelmoijan looginen virhe Odottamattomiin virheisiin reagoidaan poikkeuksilla Make 82
Virheen käsittely poikkeuksen sieppaaminen ja hoitaminen try { // koodi, jossa poikkeus saattaa tapahtua catch (poikkeustyyppi poikkeustapahtumaolio) { // koodi, joka suoritetaan poikkeustilanteessa // voi olla useita catch-osia, joista ensimmäinen sopiva valitaan // poikkeukset pitäisi tutkia tarkimmasta epätarkimpaan finally { // ei yleensä käytetä // koodi, joka suoritetaan aina // yleensä siivoustoimenpiteitä // (tiedoston sulkeminen, resurssien vapauttaminen) jatketaan tästä Make 83
Poikkeusluokkahierarkia Throwable Error Exception (ei-tarkisteta) (tarkistettava) RuntimeException (ei-tarkisteta) Make 84
Virhetyyppejä Error (virheitä, joista ohjelma ei voi toipua) OutOfMemory StackOverFlowError NoSuchMethodError NoSuchFieldError InstantiationError //olio liittymästä tai abstraktista luokasta IllegalAccessError //metodi tai kenttä johon ei oikeutta NoClassDefFoundError RuntimeException (virheitä, joihin voi reagoida mutta mitä tehdä?) ArithmeticException ArrayIndexOutOfBoundsException ArrayStoreException //väärän tyyppinen olio taulukkoon ClassCastException //laiton tyyppimuunnos IllegalArgumentException //laiton metodiparametri NullPointerException NumberFormatException StringIndexOutOfBoundsException Exception (virheitä, joista ohjelmoija voi toipua ja jotka on hoidettava) Make 85
Javan Exception-poikkeuksia IOException BadStringOperationException DataFormatException FontFormatException GeneralSecurityException ParseException PrinterException SQLException TimeoutException UnsupportedAudioFileException XMLParseException Make 86
Poikkeuksen heittäminen try { virhe catch (poikkeus){ try { laske(); catch (poikkeus){ laske() { virhe try { laskutus(); catch (poikkeus){ laskutus () throws poikkeus { laske(); laske() throws poikkeus { virhe Metodin otsikossa luetellaan throws sanan jälkeen kutsujalle heitettävät poikkeukset throws-sana pitää olla jos metodi heittää Exception-luokan poikkeuksen (kutsuvan metodin pitää hoitaa se: catch tai throws) Metodi voi hoitaa kutsumansa metodin Error ja RuntimeException poikkeuksen vaikkei se sitä throwssanalla vaatisikaan Kutsuva metodi voi heittää poikkeuksen edelleen omalle kutsujalleen Kumpi osaa hoitaa kutsuja vai kutsuttu? Make 87
Pakollinen poikkeuskäsittely try { FileInputStream tiedosto = avaa(); catch (FileNotFoundException e) { System.out.println( Tiedostoa ei löytynyt ); System.out.println( Antoi virheen: +e.getmessage()); public FileInputStream avaa() throws FileNotFoundException, SecurityException { return new FileInputStream( dataa.txt ); Poikkeustapahtumasta saadaan lisää tietoa Throwable- tai sen aliluokan metodeilla, esim: e.getmessage() Mitä tapahtuu SecurityExceptionille? Make 88
Vapaaehtoinen poikkeus Taulukkokäsittelyn suojaus: public class Pelaajat1 { private String[] asiakkaat = {"Kalle","Ville","Matti","Jaska"; public static void main(string[] args) { Pelaajat1 lista = new Pelaajat1(); lista.tulostajoukkue(); public void tulostajoukkue() { for (int i=0; i<=asiakkaat.length; i++) System.out.println(asiakkaat[i].toUpperCase()); Ohjelmassa virhe! Pitäisikö hoitaa poikkeuksilla vai if-lauseella? Miten poikkeuksella hoitaisit virheen? Jatkuu harjoituksessa 12 Make 89
Omat poikkeukset Tilanne, joka ei hoidu tavanomaisilla ohjausrakenteilla Odotettavissa olevat tilanteet if-lauseella Poikkeuskäsittely raskasta Metodi heittää poikkeuksen kutsujametodille, jos vain metodin kutsuja tietää tilanteen käsittelytavan Poikkeukset olioita periytyen java.lang.throwable luokasta Oma poikkeus kannattaa periyttää Exception-luokasta Oman poikkeusluokan nimi olisi hyvä päättyä Exception-sanaan Dokumentoinnissa mainitse metodin mahdollisesti aiheuttamat poikkeukset Make 90
Omat poikkeukset esimerkki try { nostarahaa(1000); catch (TiliTyhjaException tilipoikkeus) { System.out.println( Tililläsi ei ole riittävästi rahaa. ); System.out.println(tilipoikkeus.getMessage()); void nostarahaa(int summa) throws TiliTyhjaException { if (saldo < summa) throw new TiliTyhjaException(saldo); else saldo -= summa; public class TiliTyhjaException extends Exception { public TiliTyhjaException(saldo) { super( Nosto ei onnistu.tilisi saldo on +saldo+ euroa. ); Make 91
finally-lauseke public class TryFinal { public static void main(string[] args) { try { arvontarkastus(5); // Parametrin arvo määrää mikä poikkeus syntyy catch (IllegalArgumentException e) { System.out.println( Väärä parametrin arvo"); public static void arvontarkastus (int arvo) { try { int tulos = 100 / arvo; if (tulos < 0) throw new IllegalArgumentException(); catch (ArithmeticException e) { System.out.println("Nollalla jakoa ei saa tehdä"); finally { System.out.println("Olen aivan finaalissa"); Make 92
Luentoharjoitus 11 a) Minkälaisia poikkeuksia pyydystää seuraava koodin pätkä catch (Exception e) { koodia b) Mikä vikana seuraavanlaisessa poikkeuskäsittelyssä try { catch (Exception e) { catch (ArithmeticException a) { c) Minkä tyyppisiä virheitä (1-4) seuraavat tilanteet (a-d) ovat a. int[] a; 1. error a[0] = 0; 2. tarkistettava virhe b. JVM ei löydä Javan luokkia. 3. kääntäjän virhe c. Ohjelma saavuttaa tiedoston loppumerkin. 4. ei ole virhe d. Ohjelma yrittää lukea tiedostoa vaikka on jo sen lopussa. Make 93
Luentoharjoitus 12 1. Lisää Pelaaja1 luokan tulostajoukkue() metodiin taulukon takarajan ylitys poikkeuskäsittely 2. Lisää myös puuttuvan pelaajan poikkeuskäsittely 3. Siirrä taulukon ylitys poikkeuskäsittely Pelaaja1 luokan main-metodiin Make 94
TIEDOSTOT Make 95
Tietovirta Tieto keskusmuistissa Tietue Avaaminen Kirjoittaminen Lukeminen Sulkeminen Tietovirta Merkkivirta Binäärivirta Tieto pysyvässä muistissa Tiedosto Make 96
Kirjoitusluokat MERKKIVIRTA Writer FileWriter BufferedWriter BINÄÄRIVIRTA OutputStream FileOutputStream BufferedOutputStream Make 97
Esimerkki merkkien kirjoittamisesta import java.io.*; public class Tiedostoonmerkit { public static void main(string[] args){ Writer ulos; BufferedWriter puskuri; try { ulos = new FileWriter("Merkit.txt"); puskuri = new BufferedWriter(ulos); puskuri.write("tässä on tulostettavia merkkejä ); puskuri.newline(); puskuri.close(); catch (IOException ioe) { ioe.printstacktrace(); Make 98
Esimerkki binääridatan kirjoittamisesta import java.io.*; public class Tiedostoontavut { public static void main(string[] args){ OutputStream virta; Writer ulos; BufferedWriter puskuri; try { virta = new FileOutputStream("Tavut.txt"); ulos = new OutputStreamWriter(virta); puskuri = new BufferedWriter(ulos); puskuri.write("tässä on tulostettavia tavuja"); puskuri.newline(); puskuri.close(); catch (IOException ioe) { ioe.printstacktrace(); Make 99
Lukemisluokat MERKKIVIRTA Reader FileReader BufferedReader BINÄÄRIVIRTA InputStream FileInputStream BufferedInputStream Make 100
Esimerkki merkkien lukemisesta import java.io.*; public class Tiedostostamerkit { public static void main(string[] args) { BufferedReader puskuri; String rivi; try { puskuri = new BufferedReader(new FileReader("Merkit.txt")); while ((rivi=puskuri.readline())!= null){ System.out.println(rivi); puskuri.close(); catch (IOException ioe){ ioe.printstacktrace(); Make 101
Esimerkki binääridatan lukemisesta import java.io.*; public class Tiedostostatavut { public static void main(string[] args) { BufferedReader puskuri; String rivi; try { puskuri = new BufferedReader(new InputStreamReader( new FileInputStream("Tavut.txt"))); while ((rivi=puskuri.readline())!= null){ System.out.println(rivi); puskuri.close(); catch (IOException ioe){ ioe.printstacktrace(); Make 102
Esimerkki try-with-resource import java.io.*; public class TryWithResource { public static void main(string[] args) throws IOException { String rivi; try (BufferedReader lukija = new BufferedReader(new FileReader("Merkit.txt"))) { while ((rivi = lukija.readline())!= null) System.out.println(rivi); // Heittää poikkeuksen jos tiedostoa ei löydy tai // tiedoston sulkemisessa tapahtuu virhe Jokainen olio, joka täytyy sulkea on resurssi Try sulkee resurssin try-lauseen jälkeen Suljettavien resurssien täytyy toteuttaa AutoCloseable tai Closeable rajapinta Useita resursseja: try (InputStream fis = new FileInputStream(source); OutputStream fos = new FileOutputStream(target)){... Make 103
Olioiden lukeminen ja kirjoittaminen (sarjallistaminen) Sarjallistamisella olio kokonaisuudessaan kirjoitetaan tiedostoon ja se pystytään myös palauttamaan ohjelmaan entiseen muotoonsa. Luokat: ObjectInputStream ObjectOutputStream Make 104
Olion sarjallistaminen public class Auto implements Serializable { String merkki; public Auto(String m){ merkki = m; try { FileOutputStream out = new FileOutputStream( kulkuneuvot.dat ); ObjectOutputStream olioout = new ObjectOutputStream(out); Auto oma = new Auto( Volvo ); olioout.writeobject(oma); olioout.close(); catch (IOException ioe){ System.out.println(ioe.getMessage()); try { FileInputStream in = new FileInputStream( kulkuneuvot.dat ); ObjectInputStream olioin = new ObjectInputStream(in); Auto car = (Auto)olioin.readObject(); olioin.close(); catch (IOException ioe){ ioe.printstacktrace(); Make 105
File-luokka Käsittelee tiedostoja ja hakemistoja. File(String), File(String, String) boolean exists() boolean isdirectory() boolean isfile() boolean delete() boolean mkdir() boolean mkdirs() boolean renameto() Make 106
Luentoharjoitus 13 Lue rivejä kahdesta tiedostosta ja kirjoita ne kolmanteen tiedostoon. Luettavien tiedostojen tietueiden alussa on numerokenttä, jonka mukaan ne ovat järjestyksessä. Make 107
Luentoharjoitus 14 Serialisoi olioiden taulukko tiedostoon. Make 108
Luentoharjoitus 14.2 Testaa JFileChooser komponenttia. Make 109
UML Unified Modeling Language Make 110
Vaatimukset tietojärjestelmäksi Toimintomalli Käsitemalli Järjestelmämalli Ohjelmistomalli Tietokantamalli Tieto Toiminta (objekti) Make 111
Ohjelmiston kehitysvaiheet 1. Esitukimus (Vaatimusmäärittely (mitä, mahdollista)) 2. Analyysi (käyttötapauskaavio, luokkakaavio, attribuutit) 3. Suunnittelu (sekvenssikaavio, tarkennettu luokkakaavio) 4. Toteutus 5. Testaus 6. Käyttöönotto 7. Ylläpito Tehdäänkö? Mitä? Miten? Miten javalla? Make 112
Kehitystapa Vesiputousmalli Spiraalimalli Inkrementaalinen (lisäävä, täsmentävä) Iteratiivinen (toistava) Agile (ketterä), Scrum, XP, Muutokseen reagointi (suunnitelma) Nopea palautesykli, pienet tuotantoerät, vaatimuksien priorisointi, hinta-/aikavaikutukset Vuorovaikutus (työkalut) Vertaisarviointi, itseohjautuvat tiimit Asiakasyhteistyö (sopimukset) Tuoteomistaja, jatkuva mukanaolo, kiinteä projekti / muutosjoustavuus Toimiva sovellus (dokumentaatio) Make 113
Kaavioiden tarkoitus Mallintaminen Ymmärrä, yksinkertaista, kommunikoi Hierarkiset kaaviot Dokumentointi Kuvaus, koulutus, työvaiheen tulos Koodin tuottaminen Nopeus, muuttaminen Vaatimusten mallintaminen: käyttötapauskaavio Rakenteen mallintaminen: luokkakaavio Vuorovaikutuksen mallintaminen: sekvenssikaavio Käyttäytymisen mallintaminen : tilakaavio Make 114
Olioperustainen kuvaus Three Amigos = Rumbaugh, Booch, Jacobson 1996 UML on notaatio ei menetelmä Kaikkea ei tarvitse käyttää tai osata UML tukee hyvin oliopohjaista ohjelmankehitystä Kuvauksen jälkeen toteuttaminen helppoa Oliot heijastavat sovelluksen käsitemaailmaa luontevasti Olio sisältää käsitteen tiedot ja toiminnan Arkkitehtuuri suunnittelumalli (pattern, frame, template) algoritmi tietorakenteet Make 115
UML kaaviot Make 116
UML-kaaviot UML Rakennekaavio (Object) Käyttäytymiskaavio (Functional+Dynamic) Luokkakaavio Aktiviteettikaavio Vuorovaikutuskaavio Käyttötapauskaavio Tilakaavio Koostekaavio Sekvenssikaavio Komponenttikaavio Kommunikointikaavio Sijoittelukaavio Kokoava vuorovaikutuskaavio Pakkauskaavio Ajoituskaavio Make 117
UML-kaaviot Käyttäytymiskaavio (Behaviour diagram) Aktiviteettikaavio (Activity diagram) Käyttötapauskaavio (Use case diagram) Tilakaavio (State diagram) Vuorovaikutuskaavio (Interaction diagram) Ajoituskaavio (Timing diagram) Kokoava vuorovaikutuskaavio (Interaction overview diagram) Kommunikointikaavio (Communication diagram) Sekvenssikaavio (Sequence diagram) Rakennekaavio (Structure diagram) Komponenttikaavio (Component diagram) Koostekaavio (Composite structure diagram) Luokkakaavio (Class diagram) Oliokaavio (Object diagram) Pakkauskaavio (Package diagram) Sijoittelukaavio (Deployment diagram) Make 118
Käyttötapauskaavio Use case Actor ulkopuolinen toimija <<extends>> laajentaa, poikkeustapaus <<includes>> tai <<uses>> käyttää erillistä käyttötapausta Käyttötapauskuvaus on käyttötapauskaavion sanallinen tarkennus Strukturoitu teksti Toimintoluettelo Make 119
Kommentti Peruselementtejä Rakenne Luokka Tiedot Toiminnot Käyttäytyminen Tila Ryhmittely Pakkaus Kommentti Make 120
Assosiaatio Yksinkertainen assosiaatio (association) Asiakas 1 suorittaa 1..* Tilaus public class Tilaus { private Asiakas asiakas; Moninkertainen assosiaatio Kurssi 0..* osallistuu 1..50 maksaja Opiskelija public class Kurssi { private Opiskelija[] osallistujat = new Opiskelija[50]; public class Opiskelija { private ArrayList ilmoittautumiset; Make 121
Kooste Kooste (aggregation) Koulutusohjelma * 1..* Kurssi public class Koulutusohjelma { private ArrayList kurssilista; // Konstruktori voisi vaatia koulutusohjelmalle vähintään yhden kurssin public void LisääKurssi(Kurssi kurssi) { kurssilista.add(kurssi); Vahva kooste (muodoste, composition) 1 1..* Opiskelija Tentti-ilmoittutuminen lapsi ei voi elää ilman isää eikä kuulua muihin isiin public class Opiskelija{ private ArrayList ilmoittautumiset; public void Ilmoittaudu() { ilmoittautumiset.add(new Ilmoittautuminen()); Make 122
Periytyminen Yleistys (generalization, inheritance) public class Tentti extends Suoritus { Suoritus Tentti Abstrakti luokka (abstract class) public abstract class Suoritus { public abstract void laskeov(); italic Suoritus public class Tentti laskeov() extends Suoritus{ public void laskeov() { Tentti laskeov() Rajapinta (interface ja implementation) public interface Suoritus { //metodien määrittely <<interface>> Suoritus public class Tentti implements Suoritus { // metodien toteutukset Tentti Make 123
Luokat - käsite - määrittely (rajapinta) - toteutus Yhteydet (assosiaatiot) - viite - alityyppi Tiedot (attribuutit) - näkyvyys public + protected # private package ~ static (alleviivaus) - nimi (java notaatio) - tietotyyppi Toiminnot (metodit) - näkyvyys - nimi - parametrityypit - palautetyyppi Luokkakaavio Make 124
Vuorovaikutuskaavio Sekvenssikaavio Rahan nosto automaatista Asiakas Automaatti Tilitietokanta Syötä kortti Kysy tunnusluku Syötä tunnusluku Kysy nostettava määrä Syötä summa Syötä kortti ulos Tarkista käyttäjä Käyttäjä ok Tarkista summa Summa hyväksytty ja vähennetty Näytä saldo ruudulla Anna rahat Hyvästele asiakas Make 125
Tilakaavio Kuvaa yksittäisen olion täydellisen käyttäytymisen alkutila lopputila Make 126
Tilakaavio Laskun elinkaari kk-ajo Luotu postitettu Lähetetty suoritettu eräpäivä Maksamatta kuukausi kulunut 2 kertaa Maksettu vuosi kulunut Kehotus suoritettu ei suoritettu Arkistoitu vuosi kulunut Suoritettu suoritettu Perintä 6 kuukautta realisoitu Ulosotto oikeuden päätös Make 127
Komponenttikaavio, pakkauskaavio Komponentti kokoaa yhteen saman asian luokat ja tarjoaa käyttäjälle itsellisen, helppokäyttöisen palvelun (määritelmäni eroaa UML:stä) Pakkauskaavio ryhmittelee yhteenkuuluvat luokat ylläpitäjän näkökulmasta samaan hakemistoon (namespace, package) Make 128
Luentoharjoitus 15 Piirrä LUOKKAKAAVIO lukujärjestysohjelmaa varten. Lukujärjestyksiä pitäisi saada opiskelijaryhmälle, opettajalle sekä luokkahuoneelle. Make 129
Luentoharjoitus 16 Piirrä TILAKAAVIO ihanteellisesta, television kauko-ohjaimen toiminnasta. Ohjain ohjaa televisiota ja tallentavaa digiboxia. Make 130
TIETOKANTALIITTYMÄ Make 133
Tietokanta ja rajapinta Java-ohjelma Java-ohjelma JDBC API JDBC-ODBC silta Access- ODBC ajuri Oracle- ODBC ajuri Oracle ajuri MySQL ajuri Acess Oracle MySQL Make 134
Tietokanta -palvelinsovellukset Miksa 135
MySQL asennus Win -koneeseen 1. Asenna MySQL www.mysql.fi sivulta* Hallinta: Control panel+adminstrative tools+services Automatic/manual/start/stop 2. Asenna joku graafinen hallintatyökalu MySQL workbench (MySQL Administrator + MySQL Query Browser) HeidiSQL Sql-Front Netbeans Workbench 3. Luo tietokanta Käynnistä / MySQL / MySQL Server 5.0 / MySQL Command Line Client ja kirjoita CREATE DATABASE javatesti; GRANT ALL PRIVILEGES ON javatesti.* to testaaja@localhost identified by sala ; *Win7: Administrator-oikeuksilla Make 136
Yhteys tietokantaan MySQL JDBC-ajurin lataaminen (rekisteröinti): Class.forName( com.mysql.jdbc.driver ).newinstance(); // tai lataa mysql-connector-java-5.0.5-bin.jar MySQL-sivuilta // projektin library-polkuun (ajoaikana CLASSPATH) JDBC-ODBC-sillan lataaminen: Class.forName( sun.jdbc.odbc.jdbcodbcdriver ).newinstance(); Yhteys tietokantaan: // jdbc:driverityyppi://kone:portti/tietokanta String url = jdbc:mysql://localhost/javatesti ; con = DriverManager.getConnection(url, testaaja, sala ); // DriverManager luokka voidaan korvata uudemmalla DataSource // rajapinnalla (joka käyttää yhteysallasta) Make 137
Yhteys tietokantaan 193.167.92.152 Opiskelijoiden käyttöön tarjolla Linux palvelin. String url = "jdbc:mysql://193.167.92.152/javatesti"; con = DriverManager.getConnection(url, "testaaja", "salasana"); Tietokanta: javatesti Tunnus: testaaja Salasana: salasana Tietokantaa saa vapaasti käyttää TTY:n verkosta Tietokannan ylläpitäjältä (Mika) saa uusia tunnuksia mikäli tarpeen. Tietokannan ylläpitäjä ei vastaa tietojen säilymisestä Make 138
Luo SQL- taulu CREATE TABLE TUOTTEET ( TID INTEGER NOT NULL PRIMARY KEY, NIMI VARCHAR(40) NOT NULL, HINTA FLOAT, LKM INTEGER DEFAULT 0 ); Make 139
Luo SQL-indeksit CREATE INDEX TNIMI ON TUOTTEET(NIMI); Make 140
SQL-tietuetoiminnot LISÄYS INSERT INTO TUOTTEET VALUES (1, Korppu, 2.50, 10); INSERT INTO TUOTTEET (TID, NIMI, HINTA) VALUES (2, Romppu, 7.50); PÄIVITYS UPDATE TUOTTEET SET HINTA = 6.50, LKM = 100 WHERE TID = 2; POISTO DELETE FROM TUOTTEET WHERE TID = 1; Make 141
SQL-kysely Kaikki tietueet, kaikki kentät Kaikki tietueet, tietyt kentät Ehdon tietueet Tietueet järjestyksessä SELECT * FROM TUOTTEET; SELECT TID, NIMI, HINTA FROM TUOTTEET; SELECT * FROM TUOTTEET WHERE HINTA < 10 AND LKM >100; SELECT * FROM TUOTTEET ORDER BY HINTA, NIMI; Tietueita useasta taulusta SELECT A.ENIMI, A.SNIMI, T.PVM FROM ASIAKKAAT A, TILAUKSET T WHERE A.ANO = T.ANO; Make 142