Kursus i OOP og Java

Kursus i Objektorienteret programmering i Java

Åben Dokumentlicens

Dette foredragsmateriale er under Åben Dokumentlicens (ÅDL)

Du har derfor lov til frit at kopiere dette værk

Bruger du dele af værket i et nyt værk, skal de dele, der stammer fra dette værk, igen frigives under ÅDL

Den fulde licens kan ses på
http://www.sslug.dk/linuxbog/licens.html

Objektorienteret programmering i Java

OOPJ - lektion 1

Introduktion og overblik over kurset

Praktiske forhold

Forelæsning: Hvad er et program ?

Forelæsning: Brug af JBuilder

Øvelser

Opsamling m.m

Mål med lektion 1:

basal forståelse for hvad et program er

lære at bruge JBuilder, så I kan komme i gang med at programmere

Dette materiale er under Åben Dokumentlicens, se http://www.sslug.dk/linuxbog/licens.html

Kursets indhold

Programmering

I kan allerede programmere en smule

Variabler

Betingelser og løkker

Objektorienteret programmering

Objekter, klasser, konstruktører, nedarving, polymorfi

Java

Overblik over vigtige faciliteter

Programmering af grafik

Programmering af grafiske brugergrænseflader

Specielle emner kan tages op efter jeres ønske

Hvis der er tid

Om kurset

I kurset benyttes JBuilder

Brug fra CD eller hent fra http://borland.com/

Andre værktøjer kan også benyttes

Lærebogsmateriale

"Objektorienteret programmering i Java" af Jacob Nordfalk

En stor del af lærebogen findes på nettet:
http://javabog.dk/

Præsentationerne kan efterfølgende findes på: http://javabog.dk/foredrag/

Uddelte fotokopier

Hvad er et program?

Pandekager

800 g mel

4 tsk sukker

1 tsk salt

12 æg

16 dl mælk

12 spsk vand

Hæld mælk i en skål

Hæld vand i skålen

Tilsæt salt

Tilsæt sukker

Så længe der er æg tilbage:

Tag et æg

Slå ægget i stykker

Put ægget i skålen

Tilsæt mel

Rør dejen

Instruktionerne udføres en ad gangen, oppefra og ned.

Hvad er et program?

Et Javaprogram: Pandekagedej vha. en robot

...

double kiloMel = 0.8;

int tskSukker = 4;

int tskSalt = 1;

int antalÆg = 12;

int dlMælk = 16;

int spskVand = 12;

KokkeRobot.hældMælkISkål(dlMælk);

KokkeRobot.hældVandISkål(spskVand);

KokkeRobot.putSaltISkål(tskSalt);

KokkeRobot.putSukkerISkål(tskSukker);

...

Hvad er et program?

Når computeren skal gøre komplicerede ting

...

KokkeRobot.putSukkerISkål(tskSukker);

while (antalÆg > 0)

{

antalÆg = antalÆg - 1;

KokkeRobot.slåÆggetIstykker();

KokkeRobot.put1ÆgISkål();

}

KokkeRobot.putMelISkål(kiloMel);

KokkeRobot.rørDejen();

...

Foretager valg ud fra logiske udsagn

Byggeklodser til at vælge handlinger

while-sætning udfører en blok af kommandoer så længe et udsagn er falskt. Derefter fortsættes programmet

if-sætning udfører blokken af kommandoerne én gang, hvis udsagnet er sandt

Hvad er et program?

Fil med endelsen '.java'

kildekoden har en strukturdel:

public class Pandekager

{

public static void main(String[] arg)

{

...

}

}

og noget indhold - en kogebogsopskrift - kommandoer der skal udføres:

...

KokkeRobot.hældMælkISkål(dlMælk);

KokkeRobot.hældVandISkål(spskVand);

KokkeRobot.putSaltISkål(tskSalt);

KokkeRobot.putSukkerISkål(tskSukker);

...

Hvad er et program?

Til sammen en hel java-fil:

public class Pandekager {

public static void main(String[] args) {

double kiloMel = 0.8;

int tskSukker = 4;

int tskSalt = 1;

int antalÆg = 12;

int dlMælk = 16;

int spskVand = 12;

KokkeRobot.hældMælkISkål(dlMælk);

KokkeRobot.hældVandISkål(spskVand);

KokkeRobot.putSaltISkål(tskSalt);

KokkeRobot.putSukkerISkål(tskSukker);

while (antalÆg > 0)

{

antalÆg = antalÆg - 1;

KokkeRobot.slåÆggetIstykker();

KokkeRobot.put1ÆgISkål();

}

KokkeRobot.putMelISkål(kiloMel);

KokkeRobot.rørDejen();

}

}

Hvad er et program?

// Et simpelt program, der skriver "Hej verden"

// og et citat af Storm P. ud til skærmen

// Denne fil skal have navnet: HejVerden.java

public class HejVerden

{

public static void main (String[] arg)

{

System.out.println("Hej Verden!");

System.out.println("Hvornår smager en Tuborg bedst?");

System.out.println("Hvergang!");

}

}

Hej Verden!

Hvornår smager en Tuborg bedst?

Hvergang!

Kommentarer

Klassedefinitionen

main-metode

Resultat af kørsel

Hvordan køres et javaprogram

Programmørens arbejdsgang

Udviklingsværktøjet (JBuilder)

rette i programmer

oversætte java-filer

køre javaprogrammer

finde fejl (bl.a. med trinvis gennemgang)

JBuilder og projekter

Tjek at projektet forventer kildetekst det rigtige sted!

Tjek stierne i projektet

Åbn "Project Properties"

Kildekode i src/

.class-filer i classes/

Sti på .java-fil = src/ + pakke

Projekter

et projekt organiserer filer der hører sammen

hvert program i sit projekt selvom programmerne er små

holder rede på egenskaber for programmet

ikke det samme som et katalog

projekter ligger ofte i C:\Jbproject

Objektorienteret programmering i Java

OOPJ - lektion 2

Betinget udførelse

Variabel-typer

Model for beregninger

Hvordan bliver et program til ?

Mål med lektion 2:

Fortrolighed med løkker

Programmere lidt selv

I gang med for-projektet

Dette materiale er under Åben Dokumentlicens, se http://www.sslug.dk/linuxbog/licens.html

Betinget udførelse

if-sætninger

if (betingelse) kommando;

For eksempel:

if (alder >= 18) System.out.println("Du er myndig");

if (alkoholpromille > 0.5) System.out.println("Lad bilen stå");

if (pris < 500) System.out.println("Jeg køber den!");

if (alder == 18) System.out.println("Du er præcis atten år.");

if (alder != 18) System.out.println("Du er ikke atten.");

if-else-sætninger

if (betingelse) kommando1;

else kommando2;

Eksempelvis:

if (alder >= 18)

System.out.println("Du er myndig.");

else

System.out.println("Du er ikke myndig.");

Kædede if-else-sætninger

if (alder >= 18) System.out.println("Du er myndig.");

else if (alder >= 13) System.out.println("Du er teenager og ikke myndig.");

else if (alder >= 2) System.out.println("Du er et barn og ikke myndig.");

else System.out.println("Du er et spædbarn!");

Løkker

while-løkken

while (betingelse) kommando;

public class Syvtabel

{

public static void main(String[] arg)

{

int n;

n = 1;

while (n <= 10)

{

System.out.println(n+" : "+ 7*n);

n = n + 1;

}

}

}

for-løkken (kan det samme som while)

for (initialisering; betingelse; opdatering) kommando;

public class Syvtabel2

{

public static void main(String[] arg)

{

int n;

for (n=1; n<=10; n=n+1)

System.out.println(n+" : "+ 7*n);

}

}

De vigtigste simple variabeltyper

Konvertering

automatisk hvor mængden af mulige værdier udvides

eksplicit hvis mængden af mulige værdier indskrænkes

int x;

double y;

x = 15;	// OK

x = 15.1;	// Fejl

x = 15.0;	// Fejl

y = x;	// OK - implicit konvertering

x = y;	// Fejl

x = (int) y;	// OK - eksplicit konvertering

Model for udregninger

int x;

double y;

x=3;

y=2.9;

x = (int) ( x + y + x / 4 );

Regnestykket deles op i delberegninger

delresultat1 = x + y;

delresultat2 = x / 4;

delresultat3 = delresultat1 + delresultat2;

delresultat4 = (int) delresultat3;

x = delresultat4;

Der sættes type på delresultaterne

double delresultat1;

int delresultat2;

double delresultat3;

int delresultat4;

Typer på værdier og variable lægges fast, når programmet bliver oversat

Test hinanden

Slå op på afsnit 2.8 (Test dig selv)
Hvis I kan svare på spørgsmålene herunder, kan I være rimelig sikker på, at I har forstået alt det væsentlige i kapitlet.
Sæt jer sammen to og to og hør hinanden i spørgsmålene.
I afsnit 2.9 er nogle vejledende svar

Hvad er kommentarer? Hvordan skrives de?

Hvordan kommer man fra at skrive et program til at køre det?

Hvis en klasse (et program) hedder Xyz, hvad skal kildetekstfilen så hedde?

Hvad er en variabel?

Hvad bruges dens navn til?

Hvad bruges dens type til?

Beskriv nogle variabeltyper.

Hvordan giver man en variabel en værdi?

Hvad med typekonvertering?

Hvordan skrives en if-else-sætning (betinget udførelse)?

Hvad gør { og }?

Hvad er en løkke? Hvordan laver man en? Giv et eksempel.

Hvilke slags fejl findes der?

UML og klasserelationer

UML og klasserelationer

Rederi og Gade har en Spiller.

Helle, Start, Rederi og Gade er-et Felt.

Samlinger af data

Collection: Samling af data

Indeholder metoder fælles for alle datastrukturer

List: Ordnet liste

To klasser implementerer List: ArrayList og LinkedList.

Set: Uordnet mængde

HashSet implementerer Set.

SortedSet: Sorteret mængde

TreeSet implementerer Set.

Samlinger af data

Eksempel på brug af liste

List liste;

liste = new ArrayList();

liste.add("æh"); // alle samlinger af data

liste.add("øh",0); // kun lister

Gennemløb v.hj.a. tællevariabel

for (int i=0; i<liste.size(); i++) {

String s = (String) liste.get(i);

// gør noget med s

System.out.println(s);

}

Gennemløb v.hj.a. iterator

for (Iterator iter=liste.iterator(); iter.hasNext(); ) {

String s = (String) iter.next();

// gør noget med s

System.out.println(s);

}

Man kan få et iterator-objekt ved at kalde iterator() på enhver datastruktur (Collection)

Et (lille) objekt, der hjælper
med at gennemløbe data

En Map (da.: afbilding) beskriver nøgle-værdi-par
HashMap ord = new HashMap();
ord.put("estas", "(det) er");
ord.put("bona", "god");
ord.put("granda", "stor");
ord.put("longa", "lang");
ord.put("hundo", "hund");
esperantoOrd = "granda";
// slå esperantoordet op og få det danske ord
danskOrd = (String) ord.get( esperantoOrd );

Afbildninger
(nøgleindekserede lister)

Hashtabeller

hashCode() beregner hashkoden af et objekt

en 'næsten' unik nøgle, beregnet ud fra objektets data

et andet objekt med samme data har samme hashkode

andre objekter har en anden hashkode (i 99% af tilfældene)

alle de almindelige klasser har en god hashCode()-metode

hashkoden/nøgleværdien anvendes som indeks i et (stort) array, hvor elementet gemmes.

Hvis man vil slå et bestemt objekt (nøgle) op, beregnes dens hashværdi og der slås op på det pågældende indeks

2D-grafik

Figurer

2D-grafik

(prøv det)

Java2D – demo

Prøv selv demo i jdk1.4/demo/jfc/Java2D/Java2Demo.jar

Grafiske komponenter

import java.awt.*;

public class GrafiskVindue extends Frame

{

Label labelHvadErDitNavn = new Label();

TextField textFieldNavn = new TextField();

public GrafiskVindue() {

try {

jbInit();

}

catch(Exception e) {

e.printStackTrace();

}

}

private void jbInit() throws Exception {

labelHvadErDitNavn.setText("Hvad er dit navn?");

labelHvadErDitNavn.setBounds(new Rectangle(15, 69, 108, 15));

textFieldNavn.setText("Jacob");

textFieldNavn.setBounds(new Rectangle(141, 61, 112, 29));

this.setLayout(null);

this.add(textFieldNavn, null);

this.add(labelHvadErDitNavn, null);

}

public void paint(Graphics g)

{

g.drawLine(0,0,50,50);

g.fillOval(5,20,300,30);

g.setColor(Color.green);

String navn = textFieldNavn.getText();

for (int i=0; i<50; i=i+10)

g.drawString("Hej "+navn+" !",100+i,30+i);

}

}

Design-fanen

Visuelt designområde

Struktur af programmet

Egenskaber (og hændelser) på valgt element

Komponentfaner

Visuelt design af et grafisk program

Hule pile: er-en-relationer (dvs. nedarvning)

De andre pile: har-relatioer

En container har nul til mange komponenter

Hver komponent har/tilhører én container

Tilsvarende med CheckboxGroup og Checkbox

Komponenter og containere

Komponenter er programmørens byggeklodser

De kan bruges igen og igen i mange sammenhænge

De kan sættes sammen på alle mulige måder

De er nemme at indstille

Udviklingsværktøj kan generere programkoden for programmøren

Grafiske brugergrænseflader er som regel helt bygget op af komponenter!

Komponenter i Java hedder Javabønner (eng.: JavaBeans)

Genbrugelige komponenter

Komponentbaseret udvikling

Layout-managere

GridBagLayout

BorderLayout

FlowLayout

intet layout (null)

BoxLayout

Komponentbaseret udvikling

Demonstration af brug at komponenter i et udviklingsværktøj

Kursusopgave

Runde i plenum

Hvad kunne du tænke dig at lave projektopgave om?

Er du åben over for flere deltagere?

Diskussion to og to

Udfærdige/diskutere krav til hvert projekterne

Diskutere mulige teknologier

Diskutere om eksisterende (Open Source-)projekt kan danne udgangspunkt eller komponent herfra kan hjælpe

Hjemmeopgave fra sidste gang:

Beskriv din ide til kursusopgave (10-30 linier)

Kursusopgave

Kursusopgaver

Hønsespil - Ebbe

Regnskabssystem m flere brugerflader - Kim J

Yatzy for flere spillere - Ratha

Regelbaseret produktkonfigurator - Michael C

Styring af astronomisk kiggert (prototype t afg.proj) - Mikael M

Generere .h-filer og dokumentation fra database - Michael K

Netværksovervågningsværktøj: Nødstrømsanlæg, tavler - Peter

Forudsige farten af en sejlbåd (empirisk/modelforsøg) - Kim H

Visuel GIS-konfiguratioseditor (XML) - Christian

Racerbilspil over netværket(!) - Thomas og Haris

Grafisk overvågning af driftsdata - Carl

Rapportkonvertering/håndtering? - Anders og Atle

Visuel formel-editor (a la Word) - Preben

Regnskabssystem - Mikala

Nyt i JDK 1.5: ny syntaks

(http://java.sun.com/j2se/1.5.0/docs/relnotes/features.html)

Generiske klasser (generics/parametriserede typer)

Stærkere typesikkerhed. Eks.: ArrayList af strenge:

ArrayList<String> sl = new ArrayList<String>();

Nemmere for-løkke

Kan gennemløbe enhver datastruktur (bruger skjult Iterator på Collections-klasser og tællevariabel på almindelige arrays)

for(String s : sl) { System.out.println(s); }

Automatisk konvertering mellem simpel type og objekt

Map<String, Integer> navnTilCPR = new HashMap<String, Integer>();

navnTilCPR.put("Jacob Nordfalk", 010171); // boxing af int 010171

int cpr = navnTilCPR.get("Jacob Nordfalk"); // unboxing af Integer 010171

Typesikre opremsninger (typesafe enums)

public enum MainMenu {FILE, EDIT, FORMAT, VIEW};

Variabelt antal argumenter til en metode (array af arg)

Import af klassemetoder og -variabler (static import)

import static java.lang.Math.*; ... x = 2*PI; y = sin(x); ...

Metadata (Annotations)

Nye faciliteter i JDK 1.5

Nemmere læsning og skrivning af tekst

printf-lignende formatering med java.util.Formatter

System.out.format("Local time: %tT", Calendar.getInstance());

// -> "Local time: 13:34:18"

// Writes formatted output to System.err.

System.err.printf("Unable to open file '%1$s': %2$s",

fileName, exception.getMessage());

// -> "Unable to open file 'food': No such file or directory"

Regulære udtryk og indlæsning med java.util.Scanner

java.util.Scanner tastatur = new java.util.Scanner(System.in);

System.out.println("Tast et tal herunder og tryk retur:");

double svar = tastatur.nextDouble(); // læs tal fra tastaturet

System.out.println("Du indtastede "+svar+", det dobbelte er: "+svar*2);

Interfaces

Hændelser - genereret af værktøj

import java.awt.*;

public class GrafiskVindue extends Frame

{

Button buttonOpdater = new Button();

TextArea textAreaHilsen = new TextArea();

...

private void jbInit() throws Exception {

...

buttonOpdater.setLabel("opdater!");

buttonOpdater.setBounds(new Rectangle(231, 60, 91, 32));

buttonOpdater.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

buttonOpdater_actionPerformed(e);

}

});

textAreaHilsen.setText("Her kommer en tekst...");

textAreaHilsen.setBounds(new Rectangle(6, 102, 316, 78));

this.add(textAreaHilsen, null);

this.add(buttonOpdater, null);

}

void buttonOpdater_actionPerformed(ActionEvent e) {

String navn = textFieldNavn.getText();

System.out.println("Opdater! navn="+navn);

textAreaHilsen.setText("Hej kære "+navn);

repaint(); // gentegn vinduet, så paint() bliver kaldt

}

...

}

Faser i programudvikling

1) Kravene til programmet bliver afdækket.

2) Analyse - hvad det er for ting og begreber, programmet handler om.

3) Design - hvordan programmet skal fungere.

4) Programmering.

5) Afprøvning (test).

Forskellige metoder har vidt forskelligt tidsforbrug og antal gentagelser af faserne!

(Uigennemtænkt) programmering (3 min, gentag uendeligt)

Vandfaldsmodellen (3 måneder, gør kun én gang)

UP (Unified Process)

XP (Ekstremprogrammering)

Analysefase

Hvad det er for ting og begreber, programmet handler om

Redskaber til objektorienteret analyse

Skrive vigtige ord op

Brugssituationer (eng.: Use Case)

Aktivitetsdiagrammer, systemsekvensdiagrammer o.lign.

Skærmbilleder

Vi bruger nu 10 minutter til hvert punkt!

Fremlæggelse næste gang!

Skrive vigtige ord op

Skriv alle de navneord (i ental) eller ting op, man kan komme i tanke om ved problemet.

Ud for hver ting kan man notere eventuelle egenskaber (ofte tillægsord) og handlinger (ofte udsagnsord), der knytter sig til tingen.

Yatzyspil- antal spillere

Terning - værdi, kaste, holde

Raflebæger - kombination, ryste, holde

Blok - skrive spillernavn på, skrive point på

Spiller - navn, type (computer/menneske)

Computerspiller - strategi (dum/tilfældig, grådig, strategisk)

Menneskespiller

Regel (kunne også kaldes en mulighed eller et kriterium) - opfyldt, brugt, antal point

Lager - hiscore

Brugssituationer (eng.: Use Case)

Som diagrammer ---------->

På listeform (anbefales):

Primær aktør

Brugeren, hvis tur det er

Interessenter

Systemet

Tilstand før

Det er brugerens tur

Tilstand efter

Bruger har valgt felt i blokken og alle pointtal er opdateret

Hovedscenarie

Bruger trykker på "kast terninger"

Terninger, der ikke er holdt får en ny tilfældig værdi

Bruger vælger terninger der skal holdes
(punkt 1-3 gentages maks. 3 gange)

Systemet viser en liste af mulige felter i blokken

Bruger vælger et felt

...

Alternativer til hovedscenarie

2a. Alle terninger er holdt: Advarselsvindue dukker op: "Vil du afslutte kastene?"

Brugssituationer (eng.: Use Case)

Skabeloner til listeform

http://alistair.cockburn.us/usecases/usecases.html

http://usecases.org/

Aktivitetsdiagrammer, systemsekvensdiagrammer o.lign.

Skærmbilleder

Indkapsling

Veldesignede moduler indkapsler (eng.: encapsulate) informationerne og skjuler deres repræsentation for andre moduler ("klienter"), der bruger modulet

"Need to know"-princip

Hvis et modul ikke har behov for at vide det, får det det ikke at vide

Klienter skal vide hvad et modul gør, ikke hvordan det gør det

Princip:

Adskil et moduls (et objekts) implementation fra grænsefladen (interfacet) til modulet.

Indkapsling med pakker

Et modul, der består af flere klasser, kan lægges i sin egen pakke

metoder/variabler, der er interne for modulet erklæres med pakke-synlighed (ingenting)

modulets klasser indkapsles derved, så at klasserne kan tilgå hinandens metoder/variabler, mens de ikke er synlige udefra

Designfase

Hvordan skal programmet fungere

Redskaber til objektorienteret design

Ord til klasser

Kollaborationsdiagrammer

Klassediagrammer

Vi bruger nu 10 minutter til hvert punkt!

Fremlæggelse næste gang!

Ord til klasser

Tommelfingerregler:

Navneord (substantiver) i ental bliver ofte til klasser

Klassenavne skal altid være i ental

Udsagnsord (verber) bliver ofte til metoder

Kollaborationsdiagrammer

Husk ansvarsområder

Forskelligt antal => forskellige klasser

Tegn (har)relationer på

Klassediagrammer

To-vejs-redigering med et UML-udviklingsværktøj

TogetherJ

JDeveloper

PoseidonUML

Rekursion (hvis interesse)

Listning af filer i undermapper?

import java.io.*;

public class ListFilerRekursivt

{

public static void main(String[] arg)

{

File kat = new File("."); // det aktuelle katalog

listKatalog(kat);

}

private static void listKatalog(File kat)

{

File[] filer = kat.listFiles();

for (int i=0; i<filer.length; i++)

{

File f = filer[i];

if (f.isDirectory())

{

System.out.println("Katalog "+f+":");

listKatalog(f);

System.out.println("Katalog "+f+" slut.");

} else {

System.out.println(f);

}

}

}

}

Rekursion (hvis interesse)

Hvad skriver dette program ud?

public class Rekursionsopgave

{

public static String kaldRekursivt(String s)

{

if (s.length()<=1) return s;

String førsteTegn = s.substring(0,1);

String resten = s.substring(1);

String resten2 = kaldRekursivt( resten );

String detHele = resten2 + førsteTegn;

return detHele;

}

public static void main(String[] arg)

{

String resultat = kaldRekursivt("Hej verden!");

System.out.println(resultat);

}

}

Samtidighedsproblemet

Hvis 2 tråde kommunikerer

Fejl, der er svære at finde

Løsninger

Semaforer

Synchronized (obj)

Dyr i CPU-tid!!

obj.wait() og obj.notify()

Flertrådede designmønstre

Med JDK1.5: java.util.concurrent

public class BenytSnakkesagligePersoner

{

public static void main(String[] arg)

{

SnakkesagligPerson p = new SnakkesagligPerson();

// Opret ny tråd, klar til at udføre p.run()

Thread t = new Thread(p);

t.start(); // Nu starter personen med at snakke

// Det kan også skrives meget kompakt

new Thread(new SnakkesagligPerson()).start();

}

}

Flertrådet programmering - resumé

public class SnakkesagligPerson implements Runnable

{

public void run()

{

for (int i=0; i<5; i++)

{

System.out.println("Bla bla bla "+i);

try { Thread.sleep(ventetid); }

catch (InterruptedException e) { }

}

}

}

JDBC – databaseadgang

JDBC – databaseadgang

Lave JDBC-ODBC-bro til Access-fil

Eksempel:

1. Denne computer

2. Kontrolpanel

3. Administration

4.

5.

6

7

Forbindelse til database (MySQL)

Installér MySQL

Hent fra mysql.com

test-database god i starten

Grafiske værktøjer

Installér JDBC-driver

Connector/J fra mysql.com

Læg JAR-fil i java/jre/lib/ext/

Kontakt test-database:

Forberedte SQL-kommandoer

import java.sql.*;

public class ForberedtSQL {

public static void main(String[] arg) throws Exception

{

Class.forName("com.mysql.jdbc.Driver");

Connection con = DriverManager.getConnection("jdbc:mysql:///test");

// Forbered kommandoerne til databasen, f.eks. i starten af programmet:

PreparedStatement indsætPstm = con.prepareStatement(

"INSERT INTO kunder (navn,kredit) VALUES(?, ?)");

PreparedStatement hentPstm = con.prepareStatement(

"SELECT navn, kredit FROM kunder WHERE navn=?");

// under programudførelsen kan de forberedte kommandoer udføres mange gange:

for (int i=0; i<100; i++)

{

indsætPstm.setString(1, "Brian");

indsætPstm.setInt(2, i);

indsætPstm.execute();

indsætPstm.setString(1, "Hans' venner"); // bemærk ' i strengen

indsætPstm.setInt(2, 1042+i);

indsætPstm.execute();

hentPstm.setString(1, "Hans' venner"); // bemærk ' i SQL-forespørgslen

ResultSet rs = hentPstm.executeQuery();

// man løber igennem svaret som man plejer

while (rs.next())

{

String navn = rs.getString(1);

double kredit = rs.getDouble(2);

System.out.println(navn+" "+kredit);

}

}

}

}

Samlede batch-opdateringer

import java.sql.*;

public class Batchopdateringer

{

public static void main(String[] arg) throws Exception

{

Class.forName("com.mysql.jdbc.Driver");

Connection con = DriverManager.getConnection("jdbc:mysql:///test");

PreparedStatement pstmt = con.prepareStatement(

"INSERT INTO kunder (navn,kredit) VALUES(?, ?)");

pstmt.setString(1, "Hans");

pstmt.setInt(2, 142);

pstmt.addBatch();

pstmt.setString(1, "Grethe");

pstmt.setInt(2, 242);

pstmt.addBatch();

// send ændringer til databasen

pstmt.executeBatch();

}

}

Uden automatisk commit

import java.sql.*;

public class UdenAutocommit

{

public static void main(String[] arg) throws Exception

{

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection forb = DriverManager.getConnection(

"jdbc:oracle:thin:@ora.javabog.dk:1521:student","jacob","jacob");

try {

forb.setAutoCommit(false);

Statement stmt = forb.createStatement();

stmt.executeUpdate("insert into KUNDER(NAVN,KREDIT) values('Jacob',-17)");

stmt.executeUpdate("insert into KUNDER(NAVN,KREDIT) values('Brian', 0)");

// flere transaktioner ...

System.err.println("Alt gik godt, gør ændringerne forpligtigende");

forb.commit();

}

catch (Exception e)

{

e.printStackTrace();

System.err.println("Noget gik galt! Annullerer ændringerne...");

forb.rollback();

}

finally

{

// Husk at sætte auto-commit tilbage, af hensyn til andre transaktioner

forb.setAutoCommit(true);

}

}

}

import java.sql.*;

public class BenytMetadataOgUdskrivTabel

{

/** Udskriver et ResultSet pænt. Finder selv ud af kolonnenavnene. */

public static void udskriv(String titel, ResultSet rs) throws Exception {

ResultSetMetaData rsmd = rs.getMetaData();

int antalKolonner = rsmd.getColumnCount();

System.out.println();

System.out.println(" --------- " + titel + " ("+antalKolonner+" kolonner)");

// udskriv kolonnenavnene

for (int i=1; i<=antalKolonner; i++) skrivFormateret(rsmd.getColumnName(i));

System.out.println();

// udskriv cellerne i hver række

while (rs.next())

{

for (int i=1; i<=antalKolonner; i++) skrivFormateret(""+rs.getString(i));

System.out.println();

}

System.out.println(" -----------------------------");

}

public static void main(String[] arg) throws Exception

{

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection forb = DriverManager.getConnection(

"jdbc:oracle:thin:@ora.javabog.dk:1521:student","jacob","jacob");

DatabaseMetaData dmd = forb.getMetaData();

System.out.println("DatabaseProductName = "+dmd.getDatabaseProductName());

System.out.println("DriverName = "+dmd.getDriverName());

System.out.println("MaxRowSize = "+dmd.getMaxRowSize());

ResultSet rs = dmd.getTables(null, "JANO", "%", null);

udskriv("tabeller i databasen", rs);

Statement stmt = forb.createStatement();

rs = stmt.executeQuery("select * from KUNDER");

udskriv("kunder", rs);

}

public static void skrivFormateret(String str) {

System.out.print(str);

String KOL = " | ";

if (str.length()<KOL.length()) System.out.print(KOL.substring(str.length()));

}

}

Metadata

import java.sql.*;

public class BenytMetadataOgUdskrivTabel

{

/** Udskriver et ResultSet pænt. Finder selv ud af kolonnenavnene. */

public static void udskriv(String titel, ResultSet rs) throws Exception {

ResultSetMetaData rsmd = rs.getMetaData();

int antalKolonner = rsmd.getColumnCount();

System.out.println();

System.out.println(" --------- " + titel + " ("+antalKolonner+" kolonner)");

// udskriv kolonnenavnene

for (int i=1; i<=antalKolonner; i++) skrivFormateret(rsmd.getColumnName(i));

System.out.println();

// udskriv cellerne i hver række

while (rs.next())

{

for (int i=1; i<=antalKolonner; i++) skrivFormateret(""+rs.getString(i));

System.out.println();

}

System.out.println(" -----------------------------");

}

public static void main(String[] arg) throws Exception

{

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection forb = DriverManager.getConnection(

"jdbc:oracle:thin:@ora.javabog.dk:1521:student","jacob","jacob");

DatabaseMetaData dmd = forb.getMetaData();

System.out.println("DatabaseProductName = "+dmd.getDatabaseProductName());

System.out.println("DriverName = "+dmd.getDriverName());

System.out.println("MaxRowSize = "+dmd.getMaxRowSize());

ResultSet rs = dmd.getTables(null, "JANO", "%", null);

udskriv("tabeller i databasen", rs);

Statement stmt = forb.createStatement();

rs = stmt.executeQuery("select * from KUNDER");

udskriv("kunder", rs);

}

public static void skrivFormateret(String str) {

System.out.print(str);

String KOL = " | ";

if (str.length()<KOL.length()) System.out.print(KOL.substring(str.length()));

}

}

Metadata

Opdatere og navigere i ResultSet

De fleste ResultSet har metoder til at bevæge sig aktivt rundt i svaret og endda opdatere databasen gennem svaret.

Det gøres med f.eks.:

Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,

ResultSet.CONCUR_UPDATABLE);

ResultSet rs = stmt.executeQuery("select NAVN, KREDIT from KUNDER");

Derefter kan man navigere rundt i ResultSet-objektet med f.eks.:

rs.absolute(3); // går til 3. række i svaret (regnet fra 1 af)

rs.previous(); // går en række tilbage (modsatte af next())

rs.first(); // går til starten af svaret (svarende til rs.absolute(1))

rs.relative(3); // går 3 rækker frem, dvs. til 4. række

int r = rs.getRow();// giver hvilken række vi nu er i (her returneres 4)

Man kan ændre i data med f.eks.:

rs.updateString("NAVN", "Jakob"); // ændrer kundens navn til Jakob

rs.updateRow(); // opdaterer rækken i databasen

rs.moveToInsertRow(); // flyt til speciel indsættelses-række

rs.updateString("NAVN", "Søren"); // sæt navn

rs.updateDouble("KREDIT", 1000); // sæt kredit

rs.insertRow(); // indsæt rækken i databasen

rs.moveToCurrentRow(); // gå væk fra speciel indsættelsesrække

Derudover findes cancelRowUpdates(), der annullerer opdateringer i en række, deleteRow(), der sletter den aktuelle række fra både svaret og databasen, refreshRow(), der opfrisker ResultSet-objektet med de nyeste data.

Programmere i pakker

En pakke: En samling af relaterede klasser

En klasse svarer til en fil på filsystemet

En pakke svarer til et underkatalog på filsystemet

// Filnavn: src/minPakke/Klasse1.java

package minPakke;

import java.util.*;

public class Klasse1

{

public void snak()

{

System.out.println("Dette er Klasse1, der taler!");

}

}

// Filnavn: src/BenytPakker.java

import minPakke.*;

import java.util.*;

public class BenytPakker

{

public static void main(String[] arg)

{

Klasse1 a = new Klasse1();

a.snak();

}

}

Afprøvning (test)

Vigtigt hvis man ønsker programmer af høj kvalitet

Formål: At finde (logiske) fejl

Psykologisk modstrid

Jo tidligere fejl findes, desto lettere (og dermed billigere) er det at finde dem.

Afprøvning bør foregå på alle stadier af udviklingsprocessen.

Unit testing:

Hver enhed (klasse) afprøves uafhængigt før enhederne integreres i hele systemet.

Integrations- og systemtest:

Afprøve delene og hele systemet samlet.

Accepttest/slutbrugertest:

Sikrer at sytemet opfører sig som forventet af brugeren.

Afprøvningsstrategier

Blackbox testing

Afprøvning af delens grænseflade til resten af systemet.

Whitebox testing

Afprøvning sker i forhold til at man ved hvordan delens er implementeret (den indre logik og kodestruktur).

Blackbox Testing

Ækvivalensinddeling:

Mængden af det mulige input inddeles i ækvivalensklasser.

Grænseværider bør afprøves.

Mængden af det mulige input bør indeholde både gyldigt og ugyldige input.

Positiv afprøvning:

Testtilfælde som forventes at gå godt.

Negativ afprøvning:

Testtilfælde som forventes at gå galt.

JUnit

Et system til Unit testing (Blackbox-afprøvning af klasser).

Regressionstest

Tidligere test som er gået godt bør gentages hver gang der er foretaget ændringer i klassen.

JUnit i praksis

De fleste udviklingsværktøjer har JUnit indbygget

JBuilder

demo

BlueJ

Kan interaktivt ”optage” afprøvningseksempler

demo

Javadoc

/**

* Eksempel på en kommenteret klasse.

*/

public class EnKommenteretKlasse

{

/**

* Et eksempel på en metode. Metoden tjener

* til at vise hvordan javadoc virker.

*

* @param enStreng strengen

* @param etTal tallet

*

* @return strengen og tallet sat sammen

*/

public String enMetode(String enStreng,

int etTal)

{

return enStreng+etTal;

}

}

javadoc EnKommenteretKlasse.java

De vigtigste klasser i jeres projekt skal
være dokumenteret med Javadoc!

JAR-filer

JAR-fil er en ZIP-fil med klasser

jar cf program.jar BenytPakker.class minPakke

zip -r program.jar BenytPakker.class minPakke

Værktøjet kan lave den for en!

Oprettelse af eksekverbare JAR-filer

JAR-fil med META-INF/MANIFEST.MF

Her er klassen med main-metoden angivet

Kan aktiveres ved dobbeltklik (ligesom .exe-fil) eller med
java -jar program.jar

Manifest-Version: 1.0

Main-Class: BenytPakker

Manifest-Version: 1.0

Created-By: 1.4.2 (Sun Microsystems Inc.)

Main-Class: java2d.Java2Demo

eksamen og eksamensforberedelse

http://www.cv.ihk.dk/ITD/CN/VPJ/holdinformationer.html

10 min fremlæggelse af projekt

Vigtigt at rapportens bilag er nemme at finde rundt i!

Hvis du vil vise programmet så hav det klar på forhånd!

10 min spørgmål i pensum

Tjek af generel viden

Åben Dokumentlicens

Dette foredragsmateriale er under Åben Dokumentlicens (ÅDL)

Du har derfor lov til frit at kopiere dette værk

Bruger du dele af værket i et nyt værk, skal de dele, der stammer fra dette værk, igen frigives under ÅDL

Den fulde licens kan ses på
http://www.sslug.dk/linuxbog/licens.html

Dette dokument indeholder transparenter til et aftenkursus i OOP og Java på IT-Diplomuddannelsen. Det er inddelt i 14 lektioner og følger den foreslåede lektionsplan.

Jeg har valgt at udgive dem som et samlet dokument fordi det gør dem nemmere at tilrette til andre undervisningsforløb. Alt i dette dokument må således frit mangfoldiggøres og tilrettes efter behov (det kunne f.eks. være at der blev brugt et andet udviklingsmiljø end JBuilder).

Visse dele er direkte udklip fra bogen. Er der andre dele eller figurer fra bogen du kunne tænke dig at få med i dine præsentationer så skriv til mig: nordfalk@mobilixnet.dk .

Transparenterne bærer naturligvis præg af min undervisningsstil - som blandt andet forudsætter at eleverne selv læser stoffet, så det er kun nødvendigt at gennemgå centrale pointer i timerne. Har du lavet nogle gode præsentationer og undervisningsmateriale som du tror andre kunne få glæde af så modtager jeg dem gerne og lægger dem på bogens hjemmeside http://javabog.dk (dette gælder også præsentationer på dansk der gør brug af andre bøger).

Om ugesedlerne

Der er flere øvelser til hver uge end eleverne kan nå at lave til timerne. Underviseren kan vælge om eleverne så skal forsøge at lave dem hjemme, om de er valgfrie eller om nogle af dem skal stryges.

Jacob Nordfalk.

Præsentatoner til 'Objektorienteret programmering i Java'

Præsentatoner til lærebogen 'Objektorienteret programmering i Java' af Jacob Nordfalk

2004-08-30T12:23:21