Praktikum nr. 1
Teemad
Esmatutvus Javaga.
Käivitamine käsurealt. Andmete sisestamine
klaviatuurilt.
Pärast selle praktikumi
läbimist üliõpilane
- oskab koostada ja
käivitada väga
elementaarseid Java
programme;
- oskab nimetada
mõned olulised erinevused Java
ja Pythoni
vahel,
eriti need, mis teda võivad edaspidi
häirida;
- ei karda Javat;
- ei karda kaaslastelt ja
õppejõult
nõu küsida;
- lahendab oma kodused
ülesanded iseseisvalt ja on
nõus selle nimel ka vaeva nägema;
- tunneb vastupandamatut tahet
endale koduarvutisse
või sülearvutisse Java
installeerida.
Märkus!
Detailid (kataloogid, versioonid jms.) võivad erinevates
arvutites (arvutiklassides) olla erinevad. Jälgige lisainfot
tahvlil jm.
Linuxi klassis on võimalik tekstiredaktorina
kasutada programmi Kwrite, käsurearežiimi saab Gnome
Terminaliga.
Programme saab kätte valides Computer --> More
Applications, kiiremaks leidmiseks saab kasutada filtrit. Kataloogidega
saab manipuleerida töölaual oleva vastava Home
programmiga.
Kodukataloog pole ka siin sugugi nimega Z, vaid on hoopis pikema teena
kirjas.
Kompileerimine ja
käivitamine käsurealt
Java
programm ei ole esialgu tegelikult midagi muud kui lihtsalt
üks tavaline tekst, mille võime koostada
näiteks Notepad-i
või mõne teise
tekstiredaktoriga. Erinevalt Pythonist
tuleb Java
programmi algtekst
lisaks salvestamisele ja käivitamisele vahepeal ka
kompileerida. Tegelikult on muidugi olemas spetsiaalseid redaktoreid,
mis aitavad programmeerimise erinevates faasides. Esimeses
praktikumis
piirdume aga sihilikult tavalise tekstiredaktori ja
käsurearežiimiga.
Teemegi siis näiteks Notepadiga
teksti, mille salvestame
näiteks kataloogi Z:\oop nime all Tere.java.
Teksti
ei pea ise sisse toksima, vaid võib kopeerida
praktikumimaterjalist.
class
Tere {
public static void main(String[] args) {
System.out.println("Tervist!");
}
}
|
Start-nupu
ja käsu cmd
abil saab käsurearežiimi. Sealt saab Z:
ja cd
oop
abil õigesse kataloogi (Z:\oop). Kompileerimiseks
samas kataloogis anda
käsurealt käsk
>
javac Tere.java
Kui kompileerimine õnnestub, siis kompilaator mingeid
teateid ei anna ja pärast töö
lõppu ilmub uuesti käsuviip >
.
Kataloogi tekib fail Tere.class
.
See class-fail tekibki kompileerimise tulemusena. Edaspidiseks arvutiga
kasutamiseks ongi just seda faili vaja. Samas on see fail aga inimesele
suhteliselt loetamatu.
Kui kompilaator leiab programmi tekstis vigu, siis kuvab ta ekraanile
vastavad teated. Kui Windowsis ilmub veateade The
name
specified is not recognized as an internal or external command
...
või Bad
command or file name
,
siis ei
õnnestunud arvutil kompilaatorit javac
käivitada.
Sel juhul tuleks käsurealt paika panna otsimistee (andes
näiteks käsu path
"C:\Program Files\Java\jdk1.7.0_02\bin"
(sõltub
konkreetsest arvutist))
ja proovida uuesti.
Käsurearežiimis on abiks käsk dir,
samuti
üles-alla nooleklahvid ja tabeldusklahv. Proovige!
Käivitamiseks samas kataloogis anda käsurealt
käsk
>
java Tere
Tulemusena väljastatakse
Tervist!
Kui tekkis veateade Exception
in thread "main" java.lang.NoClassDefFoundError: Tere
(mis
näitab, et interpretaator ei leidnud vajalikku class-faili),
siis sisestage käsurealt set
classpath=
ja proovige
uuesti.
Esimene Java
programm
Analüüsime veidi seda programmi, mis on Pythoni
analoogilisest programmist
mõnevõrra
erinev.
Toome mõned punktid, mida tuleb silmas pidada.
(Mõned alltoodud punktid on natuke lihtsustatult toodud, aga
esialgu ei ole ehk kogu nüansirikkust vajagi.)
Klass
Javas peab kogu
programmitekst olema
esitatud klassidena.
Üks programm võib koosneda (ja väga sageli
koosnebki) mitmest klassist. Täna ajame küll
üheklassiliste programmidega läbi.
Klassinimi pannakse paika võtmesõna class
järel. Siit saab ka class-fail oma nime. (Kui näiteks
eeltoodud faili korral oleks failinimi olnud nt. Ilves.java,
siis oleks ikkagi kompileerimisel tekkinud Tere.class.)
Looksulud { }
Javas on programmi
liigendamiseks looksulud
(loogelised sulud). Taanete kasutamine ei ole otseselt kohustuslik, aga
on väga-väga soovitatav. Looksulud esinevad alati
paarikaupa ja nende vahel olev programmi osa moodustab ühe
terviku — ploki. Programmi osad asuvad sageli
üksteise sees, nii
võibki konkreetses kohas olla "avatud" hulk looksulgusid.
Jälgida tuleb, et kõik algavad looksulud ka
õiges kohas "lõpetataks". Meie
näites on kõige suurem tervik klass ise, mida
alustav looksulg on esimese real ja lõpetav looksulg
viimasel real. Teine looksulgudega piiritletud osa on meetod main.
Semikoolon ;
Javas on iga direktiivi
lõpus semikoolon. Meie
näites reas
System.out.println("Tervist!");
Peameetod
Klassis võib sisalduda erinevat laadi asju. Antud juhul on
siin vaid üks meetod.
Tegemist on peameetodiga, mille nimi on main.
Peameetodit
sisaldavat klassi nimetatakse peaklassiks ja seda on
võimalik käivitada, kusjuures programmi
täitmine algab alati just peameetodist.
public
static void main(String[] args) {
System.out.println("Tervist!");
}
Võtmesõnad public
ja static
ning tagastustüübi määraja void
on peameetodi korral kohustuslikud. Piiritlejat public
on
vaja, et peameetod oleks käituskeskkonnale
kättesaadav, piiritleja static
määrab,
et tegemist on klassimeetodiga. (Ilma selle piiritlejata oleks
tegemist
isendimeetodiga, millest räägime
nädala-paari pärast.) Kõikide
meetodite puhul on vajalik määrata
tagastustüüp. Peameetodi puhul on selleks void
—
tühitüüp,
mida kasutatakse niisuguste
meetodite puhul, mis tegelikult väärtust ei
tagasta.
Muutujat args
saab
kasutada käsurealt argumentide etteandmiseks
(põhimõtteliselt võib sellele
muutujale ka teise nime anda). Tüüp String[]
näitab, et neid argumente käsitletakse kui
sõnede järjendit. (Järjenditest
räägime järgmises praktikumis.)
Kommentaarid
Programmile saab lisada ka kommentaare —
tekstiosa, mida kompileerimisel eiratakse. Pikemad kommentaarid saab
piiritleda sümbolipaaridega /* ja */. Üherealise
kommentaari algust märgib sümbolipaar //. Nii saab
alustada kommentaari ka programmitekstiga realt, nt.
System.out.println("Tervist!");
// väljastatakse ekraanile
Kommentaarid kujul /** ... */ on kasutatavad automaatse dokumentaatori
sisendina.
Ülesanne A1
Lisage programmile teist korda direktiiv System.out.println("Tervist!");
Muutke
väljastatavat teksti! Kompileerige! Käivitage!
Kustutage esimese System.out.println
lõpust
ln
ära. Mis muutub?
Tüübid,
muutujad
Javas (erinevalt Pythonist)
peab muutuja ja ka meetodi
tagastustüüp olema ilmutatult
määratud. Kui tahame näiteks
kasutada
täisarvutüüpi muutujat a,
saame kirjeldamisel kasutada tüüpi int:
int a;
Muutujale
omistatakse väärtus
= abil.
a = 7;
Kirjeldamise
ja väärtuse omistamise saab ka ühendada:
int inimesi = 28;
Javas
on mõned algtüübid (algavad
väikese tähega):
- täisarvud: byte,
short,
int
ja long
(vastavalt 8-, 16-, 32- ja 64-bitilised);
- ujupunktarvud:
float
ja double
(vastavalt
32- ja 64-bitilised);
- Unicode-sümbolid:
char
(16-bitilised);
- tõeväärtused:
boolean
(true
või false)
Sõned ei ole Javas
algtüüp, vaid on
süsteemse klassi String
isendid. (Nendest pikemalt nädala-paari pärast.)
Põhimõtteliselt ongi uute
tüüpide (klasside) loomine Javas
programmeerimise
aluseks.
Tüübid ja
meetodid
Lisaks muutujatele peavad olema tüübid
määratud ka meetodite korral. Kui meetod ei tagasta
väärtust, siis on tagastustüübiks void
(tühitüüp). Kõigil teistel
juhtudel aga peab tagastustüüp olema
kooskõlas sellega, mis tüüpi
väärtuse meetod tagastab. Tagastatakse aga selle
avaldise väärtus, mis asub naasmisdirektiivis
võtmesõna return
järel. Lisaks peab meetodi päises olema
määratud ka parameetrite tüübid.
Vaatleme näitena meetodit, mis arvutab kahe reaalarvu
aritmeetilise keskmise.
static
double aritkeskmine(double arv1, double arv2) {
double summa = arv1 + arv2;
return summa/2;
}
Selle meetodi sisu saaks teha veel lühemaks - vaid
üherealiseks: return(arv1
+
arv2)/2;
Aga
las seal praegu olla ka olemas muutuja summa.
Ülesanne A2
Püüame nüüd selle meetodi programmi
sisse panna. Meetodite järjekord tekstis pole oluline,
täitmine algab nagunii peameetodist. Küll aga on
oluline, et ühe kirjeldus lõppeks enne, kui
järgmine algab.
class
Keskmised {
static double aritkeskmine(double arv1, double arv2)
{
double summa = arv1 + arv2;
return
summa/2;
}
public static void main(String[] args) {
double a = 1.5;
double b = 2.25;
double c = aritkeskmine(a, b);
System.out.println("Arvude " + a +" ja " + b + " aritmeetiline keskmine
on " + c);
System.out.println(aritkeskmine(-3.4,
3.4));
}
}
|
Ülesanne P1
Palun nüüd pöörduge
esimese paberiloleva ülesande juurde
ja lahendage
see koos paarilisega paberil.
Lisage peameetodis double
c
= aritkeskmine(a, b) rea
järele uus rida
System.out.println("Arvude"
+ a +" ja " + b + " summa on " + summa);
Tingimusdirektiivid
Tingimusdirektiivi üldine kuju Javas
on
if
(loogiline
avaldis)
direktiiv1
else direktiiv2
Tingimusdirektiiv algab sõnaga if
,
millele järgneb ümarsulgudes loogiline avaldis
(avaldis, mille väärtus saab olla kas
tõene või väär) ja sellele
omakorda direktiiv, mis täidetakse siis, kui avaldis on
tõene. Sõnale else
aga järgneb direktiiv, mis täidetakse siis, kui
loogiline avaldis on väär. Tingimusdirektiivi
else
-osa
võib ka üldse puududa. Ühe direktiivi
rollis võib olla ka plokk (programmilõik
looksulgude {}
vahel).
if
(loogiline
avaldis)
{direktiivid1
}
else
{direktiivid2
}
Ülesanne A3
Proovige teha mingi lihtne näide, kus on kasutatud
if-lauset.
Lülitidirektiiv
Suurema hulga harude puhul saab kasutada lülitidirektiivi,
mille üldkuju on järgmine
switch
(avaldis){
case võimalikväärtus1:
direktiivid1;
break;
case võimalikväärtus2:
direktiivid2;
break;
…
default:
direktiivid juhuks, kui
ühtegi ülaltoodud varianti ei kasutata;
Näiteks
järgmine programmilõik
int
nädalapäev = 4;
switch
(nädalapäev) {
case 1: System.out.println("Esmaspäev"); break;
case 2: System.out.println("Teisipäev"); break;
case 3: System.out.println("Kolmapäev");
break;
case 4: System.out.println("Neljapäev"); break;
case 5: System.out.println("Reede"); break;
case 6: System.out.println("Laupäev"); break;
case 7: System.out.println("Pühapäev");
break;
default: System.out.println("Vigane päev");
break;
}
Ülesanne A4
Katsetage ka lülitidirektiivi tööd.
Tsüklidirektiivid Javas
Tsüklite
programmeerimiseks
on keeles Java
mitu erinevat konstruktsiooni: kolmikpäisega
tsükkel (for),
eelkontrolliga tsükkel (while)
ja
järelkontrolliga tsükkel (do-while).
For-tsüklil on olemas ka lühem versioon
järjest nt.
järjendi kõigi elementide poole
pöördumiseks, aga
seda käsitleme edaspidi.
Ülesanne P2
Palun
lugege läbi alltoodud
kirjeldused ja visandage paberile vastavad plokkskeemid.
Üldtsüklidirektiiv
ehk
kolmikpäisega tsükkel ehk for-tsükkel:
for
(eeltegevused;
jätkamistingimus;
sammu
järeltegevused) {
//
käsud, mida tuleb täita niikaua,
// kui
jätkamistingimus kehtib
}
Tüüpiliselt
on eeltegevusteks
mingitele muutujatele algväärtuste omistamised.
Võimalikud eeltegevused on näiteks
järgmised.
int
i = 0;
Eeltegevused:
kirjeldatakse
täisarvutüüpi muutuja i
,
mis on
selle tsükli lokaalne muutuja (st. muutuja i
väärtus ei ole väljaspool tsüklit
kasutatav) ja omistatakse sellele algväärtus 0
.
kordaja =
0.5;
Eeltegevus:
omistatakse
reaalarvutüüpi muutujale kordaja
algväärtus 0.5
.
Siin
ei ole kordaja tsükli lokaalne muutuja, vaid eeldatakse, et
see muutuja on kirjeldatud juba enne tsükli täitmist
(tüüp on double
või float
).
int i = 0, summa = 0;
Eeltegevused:
kirjeldatakse
täisarvutüüpi tsükli lokaalmuutujad
i
ja summa
ning omistatakse neile algväärtused 0
.
Jätkamistingimus
tuleb seada
nii, et tsüklit täidetaks täpselt vajalik
arv kordi. Näiteks kui soovime, et tsüklit
täidetaks kolm korda, võib tsükli
eeltegevusena omistada mingile lokaalmuutujale
(tsükliloendajale) algväärtuseks nulli ja
igal sammul liita tsükliloendajale ühe.
Pärast tsükli esimest sammu on
tsükliloendaja väärtus siis 1,
pärast teist sammu 2 ja pärast kolmandat sammu 3.
Neljandat sammu me enam lubada ei tohi, seega peaks tsükli
lõpetama niipea, kui tsükliloendaja saab
võrdseks 3-ga või 3-st suuremaks.
Jätkamistingimus on lõpetamistingimuse
vastandtingimus, ehk antud juhul võib tsüklit
jätkata nii kaua, kui tsükliloendaja on veel
väiksem kolmest. Olukorda kirjeldava for-tsükli
päis on järgmine:
for
(int
i = 0; i < 3; i = i + 1)
Tsükli sammu
järeltegevuseks
on sageli mingi muutuja väärtuse suurendamine
või vähendamine teatud arvu võrra.
Näiteks
i
= i + 1;
j = j + 2;
k = k - 1;
Kõiki
neid omistamisi saab
Java-keeles
ka lühemalt kirja panna:
i++;
j+=2;
k--;
Kirjutame näiteks for-tsükli,
mis väljastab ekraanile viis korda teksti Tere!
.
for
(int
i = 0; i < 5; i++) {
System.out.println("Tere!");
}
Kui
tsükli sisu koosneb
ühest käsust, siis võib loogelised sulud
ka ära jätta.
Eelkontrolliga
tsükkel ehk while-tsükkel:
while
(jätkamistingimus)
{
// Siia
kirjutame käsud, mida tuleb täita niikaua,
// kui
tsükli päises olev jätkamistingimus kehtib.
}
See while-tsükkel
on samaväärne for-tsükliga,
millel puudub nii eeltegevus kui ka sammu
järeltegevus, s.o
for
( ; jätkamistingimus;
) {
// käsud
}
Järelkontrolliga
tsükkel ehk do-while-tsükkel:
do
{
// Siia
kirjutame käsud, mida tuleb täita niikaua,
// kui
jätkamistingimus kehtib.
}
while
(jätkamistingimus);
Pange
tähele, et erinevalt
eelkontrolliga tsüklist täidetakse
järelkontrolliga tsüklit alati vähemalt
üks kord, sest jätkamistingimuse kontroll
toimub
alles pärast tsükli sisu täitmist.
Ülesanne
P3
Kirjutage paberile iga
tsüklitüübi
jaoks vähemalt üks lihtne
ülesanne.
Ülesanne A5
Lahendage
ülesandes P3
püstitatud
ülesanded.
Andmete sisestamine klaviatuurilt.
Üsna sageli on vaja, et programm
saaks
andmeid klaviatuurilt. See on Javas
veidi
töömahukam kui Pythonis.
Vaatleme järgmist näidet:
import
java.util.Scanner;
class
Klaviatuurilt {
public
static void
main(String args[])
{
Scanner
scan = new Scanner(System.in);
System.out.println("Sisesta
täisarv");
int
taisarv
= scan.nextInt();
System.out.println("Sisesta
reaalarv");
double
ujukomaArv
= scan.nextDouble();
System.out.println("Sisestasid
täisarvu:
" + taisarv);
System.out.println("
ja
reaalarvu:
" + ujukomaArv);
}
}
|
Märgime
siin, et
esimesel real imporditakse valmisklass, mille abil
klaviatuurilt
sisselugemist teostada. Importimise käsk peab olema enne
klassi definitsiooni. Käsuga
Scanner
scan = new Scanner(System.in);
luuakse
objekt, mille abil
on võimalik klaviatuurilt sisestatud arve lugeda.
Täisarvu ja reaalarvu (ujukomaarvu) sisselugemine
klaviatuurilt toimub vastavalt meetoditega nextInt() ja nextDouble(). Kümnendkoha eraldaja (,
või
.) sõltub konkreetse arvuti seadetest.
Ülesanne A6
Koostada
programm, mis kontrollib, kas klaviatuurilt sisestatud kolm reaalarvu
saavad olla kolmnurga külgedeks.
Ülesanne A7
Koostada
programm, mis
küsib kasutajalt täisarvu ja teeb kindlaks, kas on
tegemist paarisarvuga. Programmi töö
lõpeb, kui kasutaja sisestab arvu null.
Ülesanne A8
Koostada programm, mis toob ekraanile
kilogrammi ja
naela vastavustabeli (võtame 1 kg = 2.2 naela, kuigi
täpsem oleks 2.20462262185
naela):
Kg
Nael
1
2.2
3
6.6
...
197
433.4
199
437.8
Selleks, et saada ilusat tabelit, tuleb väljundit
vormindada.
Veerud saab tekitada tabeldusmärgi abil, mis Javas on "\t".
Näiteks System.out.println("abc"+"\t"+"def");
viib sõne def
uude veergu. Ujupunktarvude vormindamiseks ja väljastamiseks
saab kasutada meetodit System.out.printf.
Näiteks System.out.printf("%.1f",1234.45);
määrab väljastatava kuju murdosa
pikkuseks 1.
Täiustage
programmi nii, et kasutaja käest küsitakse info
kilogrammide vahemiku kohta (algus, samm, lõpp).
Ülesanne A9
Koostada
programm, mis leiab
järgmise summa:

Täiustage
programmi nii, et kasutaja käest küsitakse, mitme
esimese liikme summa on vaja arvutada.
Ülesanne P4
Palun arutage ja kirjutage paberile, millised on teie esmamuljed
Javast.
Millised on suurimad erinevused Pythoniga?
Mida oleks vaja veel
üle seletada?
Keskkond Eclipse
Alates järgmisest korrast on soovitav kasutada keskkonda
Eclipse.Võiksite
ka juba täna proovida.
Eclipse on vabavara, mis
töötab
erinevatel
operatsioonisüsteemidel (Windows,
Linux,
Solaris
..). Eclipse
toetab erinevates programmeerimiskeeltes töötamist
(Java,
PHP,
C++,
...), samuti
saab tema abil töötada
nt. UML-ga. Eclipse
evib hästi palju võimalusi.
Meie vaatleme (ja esialgu vajame) neist vaid osasid.
Tegutseme Java
projektidega. Põhieesmärgiks on
algtekstide toimetamine, süntaktiline silumine ja
käivitamine. Silumise hõlbustamiseks saab panna
katkestuspunkte, mille abil saab jälgida muutujate
väärtuste muutumist.
Teie andmed asuvad töökataloogis (workspace).
Sinna
peab kasutajal olema õigus kirjutada. Meie puhul sobib
selleks nt. Z:-ketta alamkataloog oop. Iga projekt paigutub eraldi
alamkataloogi, milles siis on erinevad failid.
Püüdkem nüüd Eclipse
käivitada
- Siin arvutiklassis peaks Eclipse'i
ikoon
olema
töölaual. (Kui pole, siis leidke kataloog,
kus on uusim Eclipse.)
- Töökataloogiks
määrake
nt. kataloog Z:\oop
- Tervitusaknad
võite sulgeda, aga
võite ka neid soovi korral lugeda.
- Valige Window -->
Open Perspective --> Others ...-->
Java(default) või ärge valige midagi,
sest Java ongi
vaikimisi.
- Looge uus Java
projekt File --> New --> Java
Project või File --> New -->
Project
... --> Java Project
- Pange projektile
mõistlik nimi. Esialgu
võiks aktsepteerida vaikimisi vastuseid loomisdialoogis.
- Nüüd peaks
Package
Explorer
aknas olema teie loodud projekt olemas. Kui sellel hiire parema
klahviga klõpsata, siis avaneb menüü.
- Looge uus klass: New
--> Class, nimi alaku
suurtähega. Klassi loomise dialoogis
- jätke Package
tühjaks,
- Modifiers olgu
public,
- Superclass
olgu
java.lang.Object,
- loodavatest
meetoditest märgime ära public static void
main(String[]
args).
- Toimetiaknas
on nüüd teksti toorik.
- Kirjutage main-meetodisse
midagi mõistlikku, mis ka midagi ekraanile
väljastab,
ja
salvestage.
- Käivitage Run
--> Run või Run --> Run As
--> Java Application
- Tulemus peaks ilmuma
konsooliaknasse.
Kui soovite töötada juba varem tehtud failidega, siis
kasutage importimist File --> Import... --> General
--> File system.
Kodune ülesanne!
- Paigaldage enda
kodu- või
sülearvutisse Java.
- Proovige, kas toimib.
- Kui toimib, siis
võiks proovida ka paigaldada
keskkonna Eclipse.
- Sobiv variant
võiks olla Eclipse
Classic.
- Kontrollige, kas
Teil on moodle.ut.ee-s
juurdepääs Objektorienteeritud
programmeerimise kursusele.
Mõningaid materjale
Teaduskooli
programmeerimise kursus