f1pt
F4
Läsanvisning:
kap 6+7, vänta med 7.7, 7.8
· Metoder, parameteröverföring
· synbarhet (scope), överlagring (overloading)
· Fält
Nästa gång:
Nästa föreläsning handlar om ett exempel där
vi använder det vi lärt oss hittills och ser på
att att tolka felutskrifter från kompilatorn.
Näst-nästa gång: Rekursion kap 8
F5
1
import java.util.Scanner;
public class Interest4 {
p s void main(String[] args) {
// ##### read input #####
Scanner sc = new Scanner(System.in);
System.out.print("input amount: ");
double amount = sc.nextDouble();
S.o.print("input interest in %: ");
double interest = sc.nextDouble();
S.o.print("input nbr of years: ");
int years = sc.nextInt();
// simple error handling of input
if (amount <= 0
|| interest < 0
|| years < 1) {
S.o.p("One of amount<=0,
interst<0, year<1 ");
} else {
// compute interst TODO: method
interest = interest/100 + 1;
double result = amount;
for (int i = 1; i<=years; i++) {
result = result * interest;
}
// print result //formating TODO
System.out.println(result);
}
}
} // end Interest
F5
2
Metoder - en funktion: medel
metodhuvud, funktionshuvud, signatur
modifierare
formella
resultatvärdets typ
parametrar
metodens namn
public static
double medel(int v1, int v2){
return (v1+v2)/2.0;
} // end medel
metodens resultat
metodkropp
metodens resultat kan vara av vilken typ som
helst, även en klass.
Anrop tex:
double medel1 = medel(5, 10);
aktuella parametrar
F5
3
Ett program med metoder
public class EnkelMatematik1 {
public static double
medel(double v1,double v2){
return (v1 + v2)/2.0;
} // end medel;
//--------------------p s v main(String[] args){
// tal1 och tal2 får värden
// på något sätt
double tal1 = 2.0;
double tal2 = 3.0;
double c = 5.3;
// exempel på anrop
mv = medel(tal1, 4.0) + c;
mv = medel(tal1+4, tal2);
mv = medel(tal1, tal2);
S.o.print("Medelvärdet är: ");
S.o.println(mv);
//ett alternativ till sista raden
S.o.println(medel(tal1, tal2));
} // end main
} // end EnkelMatematik
F5
4
Antag tilldelning av 2.0 och 3.0 som ovan
mv = medel(tal1, tal1+1.0);
<=>
mv = medel(2.0, 3.0));
<=>
mv = 2.5;
2.0
3.0
medel
mv = medel(tal1, tal1+1.0);
<=>
mv = 2.5;
F5
5
Parameteröverföring
I Java överförs alltid parametrarna via
värdeanrop dvs värdet av den aktuella
parametern kopieras över till den formella
parametern.
public static int sqr(int x) {
... detaljer ointressanta
}
int tal = 5;
int resultat;
resultat = sqr(tal);
aktuell parameter
5
tal
formell parameter
5
x
värdet av tal beräknas och kopieras till x
tal och x är olika fysiska objekt
Det spelar ingen roll om dom har samma namn,
det är ändå två olika variabler:
public int sqr(int tal) {... osv}
int tal = 5;
int resultat;
resultat = sqr(tal);
F5
6
Synbarhet (Scope)
Regel: En variabel “syns” från det den
deklareras tills dess att blocket den
deklarerats i tar slut.
int global = 4;
if (<villkor>) {
int drömMoms = 3;
// här finns drömMoms och global
....
} else {
// här finns inte drömMoms
// men global finns
...
}
// här finns inte drömMoms
// men global finns
-----------------------------static double sqr(double x){
double tmp = x*x;
return tmp;
} // end sqr;
// här finns inte tmp och inte x
F5
7
Overloading (Överlagring)
Två eller flera metoder kan ha samma namn
om dom skiljer sig åt i sina parametrar.
public static int max
(int a, int b) {
if (a>b) {
return a;
} else {
return b;
}
}
public static int max
(int a, int b, int c) {
if (a>b) {...
}
public static double max
(double a, double b) {
if (a>b) {...
}
F5
8
Metoder = funktioner och procedurer
”Använd en funktion om du kan
en procedur om du måste”
Skall göra en sak bra.
Funktioner beräknar värden.
De utvidgar uttrycksdelen av språket.
Ett funktionsanrop
· är ett uttryck
· och har en (retur)typ ≠ void
· beräknas till ett värde som returneras
tal1 = ...; tal2 = ...
mv = medel(tal1, tal2);
Procedurer utför åtgärder
De utvidgar satsdelen av språket
Ett proceduranrop
• är en sats
• returnerar inget värde (returtyp = void)
System.out.print("Störst är: ");
F5
9
Vårt program med en metod – struktur
import java.util.Scanner;
public class Interest6 {
/**
// Javadoc om metoden
* InterestOnInterest ...
*/
p s double interestOnInterest
(double amount,
double interest,
int years) {
...
} // end interestOnInterest
// ----------------------------p s v main(String[] args) {
// ##### read input #####
...
// ##### compute interest #####
double result =
interestOnInterest(
amount, interest, years);
// ##### print result #####
System.out.println(result);
}
} // end Interest
Skall felhanteringen flytta med till metoden?
Ja troligen.
F5
10
/**
* InterestOnInterest computes the interest
* on the given amount during "years".
* @param amount to compute interest on
* @param interest in percentage
* @param years number of years
* @return The amount after “years” years.
* @author Erland Holmström
*/
p s double interestOnInterest
throws IllegalArgumentException(
double amount,
double interest,
int years) {
// error handling
if (amount <= 0
|| interest < 0
|| years < 1) {
throw new IllegalArgumentException(
"One of amount<=0,
interest<0, years<1");
} else {
interest = interest/100 + 1;
for (int i = 1; i<=years; i++) {
amount = amount * interest;
}
return amount;
}
} // end interestOnInterest
F5
11
Att kasta en exception
throw new
IllegalArgumentException("text");
Vanliga fördefinierade som du kan använda:
IllegalArgumentException, ArithmeticException,
IndexOutOfBoundsException,
NumberFormatException, InputMismatchException
Att fånga en exception:
(aldrig där den kastas)
try {
… satser som kan kasta en exception
}
catch(NumberFormatException e ) {
- åtgärda och fortsätt som vanligt
- e.printStackTrace();
- System.out.println(e.getMessage());
- throw e;
- throw new <Exnamn>(“<felmedd.>”);
- System.exit(1);
}
F5
12
Fält, vektorer, matriser, arrays
· Har numrerade komponenter.
· Komponenterna selekteras med index av
diskret typ, indexeras från noll till length-1
· Alla komponenter är av samma typ.
· Komponenterna kan vara objekt.
0 1
2
3
4
5
temp
temp[2]
Skapa fält:
Deklarera ett fält med 6 reella variabler:
double[] temp = new double[6];
Deklaration och “Snabbtilldelning”
med ”Array initializer”
int[] tmp = {0,1,2,3,4,5};
Fungerar bara vid deklarationen dvs
tmp ={0,1,2,3,4,5}; GÅR INTE
F5
13
Tilldela och läsa fältvärden
antag: int[] tmp = {0, 1, 2, 3, 4, 5};
Tilldelning av *ett* fältvärde
tmp[1] = 8;
//{0,8,2,3,4,5}
Tilldelning av *hela* fältet i en loop
for(int i = 0; i < tmp.length; i++) {
tmp[i] = 1;
}
läsa ett fältvärde
int value = tmp[1];
• fältet ändras inte vid läsning
• Fältets längd = tmp.length (är ingen metod)
• Index kan vara ett (heltals-)uttryck
• Fältet initialiseras automatiskt till 0
• Längden på ett fält kan inte ändras
F5
14
Bearbeta fältets värden
antag: double[] tmp = new double[5];
Mönster:
for( int i = 0; i < tmp.length; i++ ) {
// bearbeta enskilda fältvärden här
}
Multiplicera index med 2 respektive
Multiplicera innehållet med 2
for(int i = 0; i<tmp.length; i++){
tmp[i] = 2*i;
tmp[i] = 2*tmp[i];
}
//{0,2,4,6,8} mult. index*2
//{0,4,8,12,16} mult. innehåll*2
Räkna alla element < 10
// i, j är vanliga namn på loop-index
int antal = 0;
for (int i = 0; i < tmp.length; i++) {
if (tmp[i] < 10) {
antal = antal + 1;
}
} <- Här innehåller antal antalet element < 10
F5
15
Fält och metoder
Summera innehållet i ett fält
double sum = 0.0;
for (int i = 0; i < tmp.length; i++){
sum = sum + tmp[i];
}
System.out.println(sum);
Summera innehållet i fältet i en metod
p s double sumArray(double[] arr) {
double sum = 0.0;
for (int i = 0; i<arr.length; i++){
sum = sum + arr[i];
}
return sum;
}
Skapa fält genom att anropa en metod
p s double[] fillArray(int size) {
double[] tmp = new double[size];
for (int i = 0; i<tmp.length; i++){
tmp[i] = 1.0; // eller nåt
}
return tmp;
}
OBS Tester på tomma fält utelämnade. Loopar
som dessa måste man kunna skriva i sömnen!
F5
16
Kopiera ett fält
int[] f1 = {0,1,2,3,4,5};
int[] f2 = new int[6];
f2 = f1; // blir INTE som du tänkt
Du måste kopiera element för element:
for (int i = 0; i<f1.length; i++){
f2[i] = f1[i];
}
Ofta gör man detta i en metod:
static int[] copyArray(int[] arr) {
int[] tmp = new int[arr.length];
for (int i=0; i<arr.length; i++){
-->
tmp[i] = arr[i];
-->
}
return tmp;
}
Anrop
f2 = copyArray(f1);
Parameteröverföring igen:
Vad händer om vi gör arr[i] = 5;
inuti loopen? (Före resp. efter tilldelningen)
F5
17
Parameteröverföring
Regeln var: ”Värdet av den aktuella
parametern kopieras över till den formella
parametern.”
int[] f1 = {1,5,3,7,4,5,....};
int[] f2 = null;
int[] copyArray(int[] arr) {
int[] tmp = new int[arr.length];
...kopiera ... return tmp;
}
f2 = copyArray(f1);
aktuell
f1
17B27
• värdet av f1
formell param.
beräknas och kopieras
arr
till arr
17B27
• f1 och arr
pekar ut samma
minnesplats
lokal param.
f2
1A23
tmp
1A23
• Innehållet i arr
kopieras till tmp
• tmp och f2
refererar till samma
fysiska objekt
• tmp och arr tas bort, f1, f2 finns kvar
F5
18
Vanligaste felen med fält
“null pointer exception”
int[] f1 = {0,1,2,3,4,5};
int[] f2;
for (i = 0; i < f1.length; i++){
f2[i] = f1[i];
}
Test.java:10: variable f2 might not
have been initialized
f2[i] = f1[i];
^
1 error
f2 = f1; // funkar men ...
F5
19
Vanligaste felen med fält 2
mer “null pointer exception”
p s double sumArray(double[] arr) {
if( arr == null
//kolla alltid
|| arr.length == 0){ //beror på
exception (“arr not initialized”)
} else {
double sum = 0.0;
for (int i = 0; i<arr.length; i++){
... bearbeta fältet
}
“array index out of bounds”
double sum = 0.0;
for (i = 0; i <= f1.length; i++){
sum = sum + f1[i];
}
eller
int[] f1 = {0,1,2,3,4,5};
for (i = 0; i <= 6; i++){...
F5
20
Flerdimensionella fält (matriser)
Är fält med fält som värden
Raderna behöver inte vara lika långa
int[][] m = new int[3][6];
for( int i=0; i< m.length; i++ ) {
for( int j=0; j < m[i].length;
j++ ) {
m[i][j] = 0;
}
}
m innehåller nu
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
man kan även göra
int[][] m2 = {
{1, 2, 3, 4, 5, 6},
{1, 1, 1, 1},
{6, 5, 4, 3, 2, 1}
};
F5
21
Att formatera utskrifter 1
I PrintStream finns en metod som kan formatera
utskrifterna bättre: ”printf”
printf(String format, Object args)
% [flags] [width] [.precision] conversion-char
( square brackets denote optional parameters )
% start på format string
width - det minimala antalet tecken
precision - antalet decimaler
conversion-character:
d : decimal integer [byte, short, int, long]
f : floating-point number [float, double]
e : scientific notation
c : character
s : String
(det finns fler)
System.out.printf
("Calling isPrime() %.0e times,", max );
System.out.printf("%4d %8d\n", r, r*r)
@see PrintStream
@see sök på ”Java printf( ) method”
@see java.util.Formatter
(An interpreter for printf-style format strings.)
F5
22
Att formatera utskrifter 2
String class format( ) method:
”You can build a formatted String and assign
it to a variable using the static format
method in the String class. The use of a
format string and argument list is identical to
its use in the printf method.
The format method returns a reference to a
String.”
Example:
String grandTotal = String.format
("Grand Total: %-10.2f", dblTotal);
@see java.lang.String class, method format
@see java.util.Formatter class
F5
23
** Att formatera utskrifter 3
@see java.text.Format: Format is an abstract
base class for formatting locale-sensitive
information such as dates, messages, and numbers.
@see java.text.NumberFormat: NumberFormat is
the abstract base class for all number formats
@see java.text.DecimalFormat: DecimalFormat is
a concrete subclass of NumberFormat that
formats decimal numbers.
import java.util.*;
import java.text.DecimalFormat;
public class FormateraTest {
ps... void main(String[] args) {
double dollarKurs = 8.14;
double kr = new
Double(args[0]).doubleValue();
DecimalFormat f =
new DecimalFormat("0.00");
String dollars =
f.format(kr/dollarKurs);
...print(kr + " motsvarar ");
...println(dollars + " dollar");
}
}
F5
24
** Utvecklingen av printf
From Cay Horstmann's Home Page
The March of Progress
1980: C
printf("%10.2f", x);
1988: C++
cout <<setw(10) <<setprecision(2) <<showpoint <<x;
1996: Java
java.text.NumberFormat formatter =
java.text.NumberFormat.getNumberInstance();
formatter.setMinimumFractionDigits(2);
formatter.setMaximumFractionDigits(2);
String s = formatter.format(x);
for (int i = s.length(); i < 10; i++)
System.out.print(' ');
System.out.print(s);
2004: Java
System.out.printf("%10.2f", x);
2008: Scala and Groovy
printf("%10.2f", x)
(Thanks to Will Iverson for the update. He writes:
“Note the lack of semi-colon. Improvement!”)
F5
25
Ordlistan växer...
metoder (funktioner, procedurer),
parameteröverföring,
metodhuvud, funktionshuvud, signatur,
formell/aktuell parameter.
uttrycksdel, satsdel, värdeanrop, synbarhet,
scope, overloading, överlagring,
Fält, vektorer, matriser, arrays, deklarera,
index av diskret typ,
initialisera,
F5
26