Objektorienterad programmering Telefonboken igen, en bättre

Telefonboken
Objektorienterad programmering
Föreläsning 4
Telefonboken, igen.
Telefonboken igen, en bättre version
Tre klasser
Vi bygger upp programmet av
tre klasser: Entry,
SimplePhoneBook och Main
Klassen Entry
Tvådimensionella fält.
Exempel: femtonspelet.
Instanser av Entry innehåller
två strängar, ett namn och ett
telefonnummer. Förutom
konstrueraren finns två
metoder:
Modellklassen.
Ett textbaserat program.
Ett grafiskt program.
public String getName()
public String getNumber()
Telefonboken
Klassen SimplePhoneBook
Själva telefonboken; innehåller ett
fält av Entry-objekt. Metoder är
public void put(String name,
String phoneNr)
public String get(String name)
Endast en instans skapas.
Klassen Main
Klassen innehåller main, som sköter
dialogen med användaren.
Telefonboken
En jämförelse
Klassen SimplePhoneBook
public class SimplePhoneBook {
public class SimplePhoneBook {
private Entry[] book;
private int count;
private Entry[] book;
private int count;
public static void main(String [] args) {
Entry[] book = new Entry[100];
int count = 0;
public SimplePhoneBook(int size) {
book = new Entry[size];
count = 0;
}
Scanner in = new Scanner(System.in);
prompt();
while(in.hasNext()) {
String cmd = in.next();
if (cmd.equals("quit"))
System.exit(0);
else if (cmd.equals("put")) {
String name = in.next();
String nr = in.next();
book[count] = new Entry(name,nr);
count++;
}
else if (cmd.equals("get")) {
String name = in.next();
for (int i=0; i<count;i++)
if (name.equals(book[i].getName())) {
System.out.println("Number is " + book[i].getNumber());
}
} else
System.out.println("Unknown command");
prompt();
}
public SimplePhoneBook(int size) {
book = new Entry[size];
count = 0;
}
public void put(String name, String nr) {
book[count] = new Entry(name,nr);
count++;
}
public String get(String name) {
for(int i=0; i<count; i++)
if (name.equals(book[i].getName()))
return book[i].getNumber();
return null;
}
}
public void put(String name, String nr) {
book[count] = new Entry(name,nr);
count++;
}
public String get(String name) {
for(int i=0; i<count; i++)
if (name.equals(book[i].getName()))
return book[i].getNumber();
return null;
}
}
public static voi
Entry[] book
int count = 0
Scanner in =
prompt();
while(in.hasN
String cm
if (cmd.e
Syste
else if (
Strin
Strin
book[
count
}
else if (
Strin
for (
i
}
} else
Syste
prompt();
}
Telefonboken
Telefonboken, återstående problem
2-dim fält
Tvådimensionella fält
Matriser i Java
Problemet
Om samma namn sätts in igen med nytt nummer, placeras denna Entry
sist och det tidigare finns kvar.
En matris representeras i Java som ett fält av rader, där varje rad är ett fält
av tal.
Till skillnad från i matten indexerar vi alltid med början från 0.
Sökning ger bara det först insatta numret.
Förslag till lösning
3
7
4
2
Ny insättning med samma namn ska ersätta det gamla numret. I metoden
put måste vi därför börja med att se om namnet finns.
5
0
6
4
0
7
2
En sådan version (med en privat hjälpmetod getIndex) finns i
lect4code.zip.
.
Raden a[1]
1
Elementet a[2][1]
a har typen int[][]. Rita en bild över hur det ser ut i minnet!
2-dim fält
2-dim fält
Att skapa matriser
Att iterera över en matris
Exempel
Matrisen på föregående bild kan deklareras och skapas på ett av följande
två sätt:
Med många tilldelningar:
int[][] a = new int[3][4];
a[0][0] = 3;
a[0][1] = 7;
... alla element tilldelas ...
a[2][3] = 1;
Nollställning av alla element
for (int i=0; i< a.length; i++) {
for (int j=0; j < a[0].length; j++) {
a[i][j] = 0;
}
}
En sådan nästad for-sats är mycket vanlig när man arbetar med matriser.
Med initieringsuttryck:
Exempel
int[][] a = {{3,7,4,2},
{5,0,6,4},
{0,7,2,1}};
Definiera en funktion som beräknar summan av alla element i en matris.
2-dim fält
Mera linjär algebra
15-spelet
Exempel: Femtonspelet
Fysiskt spel
Klassen LinearAlgebra
Förra veckan definierade vi två funktioner
double scalarProduct(double[] a, double[] b);
double[] vectorSum(double[] a, double[] b);
Grafisk variant i Java
Lägg till en funktion som multiplicerar en matris med en (kolonn-)vektor.
15-spelet
En första analys
Spelets tillstånd
Läget (tillståndet) i spelet kan representeras med en 4x4-matris av heltal,
som innehåller talen 0–15 (0 representerar hålet).
Ett drag innebär att talet 0 i matrisen byter plats med en granne (dvs något
av talen över, under, till vänster eller till höger).
Textbaserad variant i Java
lect4code> java TextMain
1 54
d36b
af67
9e2c
Position of piece to move: 1 1
1354
d 6b
af67
9e2c
Position of piece to move: 1 2
1354
d6 b
af67
9e2c
Position of piece to move:
15-spelet
Skiss till tänkbar lösning
public class Fifteen {
public static void main(String[] args) {
int[][] state = new int[4][4];
for (int r=0; r<4; r++)
for (int c=0; c<4; c++)
state[r][c] = 4*r+c+1;
state[3][3] = 0;
Den textbaserade main-rutinen
// Blanda slumpmässigt
Vi behöver göra följande:
Initiera spelmatrisen slumpmässigt.
Om och om igen:
- Skriv ut matrisen på lämplig form.
- Läs in användarens drag.
- Uppdatera matrisen med detta drag.
while(true) {
// Skriv ut tillståndet
// Läs in användarens drag
// Om draget är tillåtet, uppdatera tillståndet
}
}
15-spelet
15-spelet
Att läsa in användarens drag
...
Scanner in = new Scanner(System.in);
while(true) {
// Skriv ut tillståndet
System.out.print("Position of piece to move: ");
int row = in.nextInt();
int col = in.nextInt();
if // (row,col) granne med hålet
// byt plats på hålet och talet i (row,col)
else
System.out.println("Cannot move piece!");
}
15-spelet
Att skriva ut tillståndet
for (int r=0; r<4; r++) {
for (int c=0; c<4; c++) {
int n = state[r][c];
if (n==0)
System.out.print(" ");
else if (n<=9)
System.out.print(n);
else
// Om n=10, skriv "a", om n=11, skriv "b",...
}
System.out.println();
}
15-spelet
Vad återstår?
Delar som hittills bara är kommentarer
Blanda slumpmässigt.
Avgör om användarens valda bit är granne med hålet.
Byt plats på den valda biten och hålet.
Utskrift av bitarna 10–15.
Förbättring: en objektorienterad design
Vi lagrar matrisen state som tillstånd i en modellklass FifteenModel,
som erbjuder endast följande metoder, förutom konstrueraren:
public void shuffle();
public boolean tryMovePieceAt(int row, int col);
public int getState(int row, int col);
Textbaserat vs grafiskt program
Det textbaserade programmet
Programmet består av två klasser, FifteenModel och TextMain.
Den senare innehåller main-rutinen och en hjälprutin för utskrift.
Det grafiska programmet
Vi kan idag inte förstå detta program fullständigt, men titta på det;
strukturen återkommer gång på gång!
Programmet består av fyra klasser:
Samma modellklass FifteenModel.
En grafisk klass FifteenPanel, för att rita upp spelet på skärmen.
En styrklass FifteenListener, som beskriver hur programmet ska
reagera på användarens mustryck.
Klassen GraphicsMain, som innehåller main-rutinen.
15-spelet
15-spelet
De två main-rutinerna
Härnäst
Det textbaserade programmet
Labb 3
I labb 3 ska vi betrakta ett program som implementerar Game of Life, en
simulering av en population celler som följer enkla regler.
I main skapas och blandas ett modellobjekt.
Sedan startar main en loop där man i varje varv skriver ut modellen, begär
en position av användaren, samt uppdaterar modellen om positionen är
OK.
(med Ctrl-C).
Programmet är grafiskt och händelsestyrt, består av fyra klasser, varav en
modellklass – och det är den ni ska skriva. Titta gärna på de övriga
klasserna, främst för att förstå modellklassens roll i programmet. Ni
behöver inte förstå dessa klasser i detalj!
Det grafiska programmet
Nästa veckas övning
I main skapas och blandas ett modellobjekt. Dessutom skapas ett
panelobjekt och ett grafiskt fönster (av klassen JFrame).
I panelobjektets konstruerare skapas ett styrobjekt.
Panelen placeras i fönstret som görs synligt på skärmen. Därefter tar main
slut – men inte programmet! Det väntar för evigt på händelser
(användarens musklick).
Vi övar på att definiera enkla klasser som mallar.
main (och därmed programmet) fortsätter tills det avbryts av användaren
Slutkommentar
Vi befinner oss nu på förvirringsmaximum – de flesta nya begrepp har
introducerats men inte hunnit smältas.
En stor del av resterande tid används för konsolidering.