Klasse voorbeelden
inhoud: voorbeeld1: dobbelsteen (Die) voorbeeld2: bankrekening (Account)
Beginselen van programmeren 10
voorbeeld3: geldstuk (Coin) voorbeeld4: rational getal (RationalNumber) voorbeeld5: aggregatie-voorbeeld (Student)
klasse voorbeelden
voorbeeld6: objecten als parameter (ParameterTester)
1
klassen en objecten
voorbeeld 1: klasse Die
de klasse met de main methode is het startpunt van een programma object-georiënteerd programmeren:
een klasse bevat data declaraties en methode declaraties
definiëren van klassen die objecten voorstellen met welbepaalde eigenschappen en functionaliteit een object heeft:
2
int faceValue … MAX = 6
een toestand een gedrag
Data declaratie(s)
Die
voorbeeld1:
roll
een dobbelsteen (met zes zijden): Die
toestand: de zijde die naar boven ligt gedrag: o.a. het werpen van een dobbelsteen, waardoor de toestand kan veranderen
van de klasse dobbelsteen kunnen een willekeurig aantal bobbelsteen-objecten geconcretiseerd (instantiated) worden
setFaceValue
Methode declaraties
getFaceValue toString
3
4
1
//******************************************************************** // Die.java // // Represents one die (singular of dice) with faces showing values // between 1 and 6. //********************************************************************
klasse Die de waarden van de data definiëren de toestand van het object
public class Die { private final int MAX = 6;
vb: Die
faceValue
een gehele waarde die aangeeft welke zijde naar boven ligt MAX maximum waarde van faceValue
private int faceValue;
de methodes definiëren het gedrag van het object vb: Die int roll ( )
bepaalt de waarde van faceValue als een random waarde uit het interval 1 tot 6
Die ( ) constructor
void setFaceValue (int value) zet de waarde van faceValue op de gespecificeerde waarde
(een mutator)
int getFacevalue ( ) geeft de waarde van faceValue
(een accessor)
// maximum face value
// current value showing on the die
//----------------------------------------------------------------// Constructor: Sets the initial face value. //----------------------------------------------------------------public Die() { faceValue = 1; } //----------------------------------------------------------------// Rolls the die and returns the result. //----------------------------------------------------------------public int roll() { faceValue = (int)(Math.random() * MAX) + 1;
String toString ( )
return faceValue;
geeft een string voorstelling met de actuele waarde van faceValue
} 5
6
//******************************************************************** // RollingDice.java // // Demonstrates the creation and use of a user-defined class. //********************************************************************
//----------------------------------------------------------------// Face value mutator. //----------------------------------------------------------------public void setFaceValue (int value) { if (value >= 1 && value <= MAX) faceValue = value; else faceValue = 1 ; // default value }
public class RollingDice { //----------------------------------------------------------------// Creates two Die objects and rolls them several times. //----------------------------------------------------------------public static void main (String[] args) { Die die1, die2; int sum;
//----------------------------------------------------------------// Face value accessor. //----------------------------------------------------------------public int getFaceValue() { return faceValue; }
die1 = new Die(); die2 = new Die(); die1.roll(); die2.roll(); System.out.println ("Die One: " + die1 + ", Die Two: " + die2); die1.roll(); die2.setFaceValue(4); System.out.println ("Die One: " + die1 + ", Die Two: " + die2);
//----------------------------------------------------------------// Returns a string representation of this die. //----------------------------------------------------------------public String toString() { String result = Integer.toString(faceValue);
sum = die1.getFaceValue() + die2.getFaceValue(); System.out.println ("Sum: " + sum); sum = die1.roll() + die2.roll(); System.out.println ("Die One: " + die1 + ", Die Two: " + die2); System.out.println ("New sum: " + sum);
return result; }
} }
} 7
8
2
de toString methode
gegevensbereik - data scope
alle klassen horen een toString methode te definiëren
Het bereik (scope) van een gegeven
de toString methode geeft een character string die het object voorstelt deze methode wordt automatisch aangeroepen wanneer een object geconcateneerd wordt met een andere string of wanneer het doorgegeven wordt aan de println methode
=het gebied van in het programma waarin aan dat gegeven kan worden gerefereerd (waar het kan worden gebruikt)
gegevens gedeclareerd op het niveau van de klasse kunnen bereikt worden door alle methodes van de klasse
gegevens gedeclareerd in een methode kunnen enkel in die methode bereikt worden: ze worden lokale gegevens genoemd
in de Die klasse: de variable result
is dedeclareerd in de toString methode
is lokaal in die methode kan elders niet gebruikt worden
9
instantie gegevens - instance data
UML klasse diagram
voorstelling van de twee Die objecten van het RollingDice programmas:
die1
faceValue
10
een UML klasse diagram voor het RollingDice programma:
5
RollingDice
Die faceValue : int
die2
faceValue
main (args : String[]) : void
2
roll() : int setFaceValue (int value) : void getFaceValue() : int toString() : String
elk object heeft haar eigen faceValue variable, en zo haar eigen toestand
11
12
3
voorbeeld 2: bankrekening (Bank Account)
driver programma’s
klasse om een bankrekening voor te stellen: Account toestand:
een driver programma is bedoeld om andere delen van een programma te gebruiken wordt dikwijls gebruikt om delen van een programma te testen
rekening nummer actueel saldo (balance) naam van de eigenaar …
wij gebruiken als programma de klasse Transactions met een main methode, die een driver is voor het gebruik van de Account klasse, waarbij verschillende van haar diensten worden gebruikt
gedrag (diensten): storting (deposit) geld afhaling (withdrawal) intrest toevoegen …
13
14
//******************************************************************** // Account.java // // Represents a bank account with basic services such as deposit // and withdraw. //******************************************************************** //----------------------------------------------------------------// Deposits the specified amount into the account. Returns the // new balance. //----------------------------------------------------------------public double deposit (double amount) { balance = balance + amount;
import java.text.NumberFormat; public class Account { private final double RATE = 0.035;
// interest rate of 3.5%
private long acctNumber; private double balance; private String name;
return balance; }
//----------------------------------------------------------------// Sets up the account by defining its owner, account number, // and initial balance. //----------------------------------------------------------------public Account (String owner, long account, double initial) { name = owner; acctNumber = account; balance = initial; }
//----------------------------------------------------------------// Withdraws the specified amount from the account and applies // the fee. Returns the new balance. //----------------------------------------------------------------public double withdraw (double amount, double fee) { balance = balance - amount - fee; return balance; }
15
16
4
//******************************************************************** // Transactions.java Author: Lewis/Loftus // // Demonstrates the creation and use of multiple Account objects. //******************************************************************** //----------------------------------------------------------------// Adds interest to the account and returns the new balance. //----------------------------------------------------------------public double addInterest () { balance += (balance * RATE); return balance; }
public class Transactions { //----------------------------------------------------------------// Creates some bank accounts and requests various services. //----------------------------------------------------------------public static void main (String[] args) { Account acct1 = new Account ("Ted Murphy", 72354, 102.56); Account acct2 = new Account ("Jane Smith", 69713, 40.00); Account acct3 = new Account ("Edward Demsey", 93757, 759.32);
//----------------------------------------------------------------// Returns the current balance of the account. //----------------------------------------------------------------public double getBalance () { return balance; }
acct1.deposit (25.85); double smithBalance = acct2.deposit (500.00); System.out.println ("Smith balance after deposit: " + smithBalance);
//----------------------------------------------------------------// Returns a one-line description of the account as a string. //----------------------------------------------------------------public String toString () { NumberFormat fmt = NumberFormat.getCurrencyInstance();
System.out.println ("Murphy balance after withdrawal: " + acct2.withdraw (430.75, 1.50));
return (acctNumber + "\t" + name + "\t" + fmt.format(balance)); }
17
}
18
bankrekening voorbeeld acct1 acct1.addInterest(); acct2.addInterest(); acct3.addInterest(); System.out.println System.out.println System.out.println System.out.println
acctNumber
72354
balance 102.56 “Ted Murphy”
name
(); (acct1); (acct2); (acct3);
} }
acct2
acctNumber
69713
balance
40.00
name
19
“Jane Smith”
20
5
constructoren - nogmaals
bankrekening voorbeeld mogelijke verbeteringen aan de Account klasse: formele get en set methodes kunnen voor alle gegevens gedefinieerd worden methodes kunnen robuster worden gemaakt, zoals nagaan of de amount parameter in de withdraw methode positief is
bij een constructor wordt geen return type opgegeven in de methode hoofding een wel eens gemaakte fout is het vermelden van return type bij een constructor; dan wordt het een “gewone” methode die (toevallig) dezelfde naam draagt als de klasse
een programmeur is niet verplicht een constructor voor een klasse te definiëren elke klasse heeft een verstek conctructor (default constructor ) zonder parameters
21
//******************************************************************** // Coin.java // // Represents a coin with two sides that can be flipped. //********************************************************************
voorbeeld 3: de Coin klasse
22
public class Coin { public final int HEADS = 0; public final int TAILS = 1;
Coin klasse gegevens: face, een integer die de actuele bovenzijde voorstelt HEADS en TAILS, integer constanten die de mogelijke toestanden voorstellen
private int face;
methodes: een Coin constructor, om een object te creëren een flip methode, om een muntstuk op te werpen een getFace methode, die de actuele bovenzijde teruggeeft een toString methode, die een string terugggeeft die kan worden geschreven
23
//----------------------------------------------------------------// Sets up the coin by flipping it initially. //----------------------------------------------------------------public Coin () { flip(); } //----------------------------------------------------------------// Flips the coin by randomly choosing a face. //----------------------------------------------------------------public void flip () { face = (int) (Math.random() * 2); }
24
6
//----------------------------------------------------------------// Returns the current face of the coin as an integer. //----------------------------------------------------------------public int getFace () { return face; }
//******************************************************************** // CountFlips.java // Demonstrates the use of a programmer-defined class. //******************************************************************** public class CountFlips { //----------------------------------------------------------------// Flips a coin multiple times and counts the number of heads // and tails that result. //----------------------------------------------------------------public static void main (String[] args) { final int NUM_FLIPS = 1000; int heads = 0, tails = 0;
//----------------------------------------------------------------// Returns the current face of the coin as a string. //----------------------------------------------------------------public String toString() { String faceName; if (face == HEADS) faceName = "Heads"; else faceName = "Tails";
Coin myCoin = new Coin();
// instantiate the Coin object
for (int count=1; count <= NUM_FLIPS; count++) { myCoin.flip();
return faceName; }
if (myCoin.getFace() == myCoin.HEADS) heads++; else tails++;
}
} System.out.println ("The number flips: " + NUM_FLIPS); System.out.println ("The number of heads: " + heads); System.out.println ("The number of tails: " + tails); }
25
26
}
de Coin klasse
instantievariabelen / instance data
eens de klasse Coin gedefinieerd is, kan ze worden gebuikt in elk programma waar we dat wensen
face variable in de Coin klasse: een instantiegegeven of instantievariabele:
het CountFlips programma gebruikt niet alle methodes van Coin, n.l. niet de toString methode dat is uiteraard toegelaten
elke instantie (elke object) van de klasse Coin heeft er een eigen exemplaar van
een klasse definieert het type van de instantievariabelen reserveert er geen geheugenruimte voor
telkens een Coin object wordt gecreëerd, wordt ook een nieuwe face variable gecreëerd de objecten van dezelfde klasse delen de methode definities, maar hebben unieke gegevensruimte hebben daardoor verschillende toestanden 27
28
7
//******************************************************************** // FlipRace.java // Demonstrates the existence of separate data space in multiple // instantiations of a programmer-defined class. //******************************************************************** public class FlipRace { //----------------------------------------------------------------// Flips two coins until one of them comes up heads a set number // of times in a row. //----------------------------------------------------------------public static void main (String[] args) { final int GOAL = 3; int count1 = 0, count2 = 0;
instantievariabelen / instance data
zie FlipRace.java class Coin
coin1 face
int face;
0
// Create two separate coin objects Coin coin1 = new Coin(); Coin coin2 = new Coin();
coin2 face
while (count1 < GOAL && count2 < GOAL) { coin1.flip(); coin2.flip(); // Print the flip results (uses Coin's toString method) System.out.print ("Coin 1: " + coin1); System.out.println (" Coin 2: " + coin2);
1
// Increment or reset the counters count1 = (coin1.getFace() == coin1.HEADS) ? count1+1 : 0; count2 = (coin2.getFace() == coin2.HEADS) ? count2+1 : 0;
29
30
}
// Determine the winner if (count1 < GOAL) System.out.println ("Coin 2 Wins!"); else if (count2 < GOAL) System.out.println ("Coin 1 Wins!"); else System.out.println ("It's a TIE!");
voorbeeld 4: rationaal getal definite van een klasse Rational om een rationaal getal voor te stellenr
}
rationaal getal: breuk van twee gehele getallen
}
sommige methodes van de klasse Rational hebben een ander Rational object als parameter
31
32
8
//******************************************************************** // RationalNumber.java // // Represents one rational number with a numerator and denominator. //******************************************************************** public class RationalNumber { private int numerator, denominator; // numerator: teller denominator: noemer //----------------------------------------------------------------// Constructor: Sets up the rational number by ensuring a nonzero // denominator and making only the numerator signed. //----------------------------------------------------------------public RationalNumber (int numer, int denom) { if (denom == 0) denom = 1;
//----------------------------------------------------------------// Returns the numerator of this rational number. //----------------------------------------------------------------public int getNumerator () { return numerator; } //----------------------------------------------------------------// Returns the denominator of this rational number. //----------------------------------------------------------------public int getDenominator () { return denominator; }
// Make the numerator "store" the sign if (denom < 0) { numer = numer * -1; denom = denom * -1; }
//----------------------------------------------------------------// Returns the reciprocal of this rational number. //----------------------------------------------------------------public RationalNumber reciprocal () { return new RationalNumber (denominator, numerator); }
numerator = numer; denominator = denom; reduce(); }
33
//----------------------------------------------------------------// Adds this rational number to the one passed as a parameter. // A common denominator is found by multiplying the individual // denominators. //----------------------------------------------------------------public RationalNumber add (RationalNumber op2) { int commonDenominator = denominator * op2.getDenominator(); int numerator1 = numerator * op2.getDenominator(); int numerator2 = op2.getNumerator() * denominator; int sum = numerator1 + numerator2;
34
//----------------------------------------------------------------// Multiplies this rational number by the one passed as a // parameter. //----------------------------------------------------------------public RationalNumber multiply (RationalNumber op2) { int numer = numerator * op2.getNumerator(); int denom = denominator * op2.getDenominator(); return new RationalNumber (numer, denom); }
return new RationalNumber (sum, commonDenominator); //----------------------------------------------------------------// Divides this rational number by the one passed as a parameter // by multiplying by the reciprocal of the second rational. //----------------------------------------------------------------public RationalNumber divide (RationalNumber op2) { return multiply (op2.reciprocal()); }
} //----------------------------------------------------------------// Subtracts the rational number passed as a parameter from this // rational number. //----------------------------------------------------------------public RationalNumber subtract (RationalNumber op2) { int commonDenominator = denominator * op2.getDenominator(); int numerator1 = numerator * op2.getDenominator(); int numerator2 = op2.getNumerator() * denominator; int difference = numerator1 - numerator2; return new RationalNumber (difference, commonDenominator); }
35
//----------------------------------------------------------------// Determines if this rational number is equal to the one passed // as a parameter. Assumes they are both reduced. //----------------------------------------------------------------public boolean equals (RationalNumber op2) { return ( numerator == op2.getNumerator() && denominator == op2.getDenominator() ); }
36
9
//----------------------------------------------------------------// Returns this rational number as a string. //----------------------------------------------------------------public String toString () { String result; //----------------------------------------------------------------// Computes and returns the greatest common divisor of the two // positive parameters. Uses Euclid's algorithm. //----------------------------------------------------------------private int gcd (int num1, int num2) { while (num1 != num2) if (num1 > num2) num1 = num1 - num2; else num2 = num2 - num1;
if (numerator == 0) result = "0"; else if (denominator == 1) result = numerator + ""; else result = numerator + "/" + denominator; return result; } //----------------------------------------------------------------// Reduces this rational number by dividing both the numerator // and the denominator by their greatest common divisor. //----------------------------------------------------------------private void reduce () { if (numerator != 0) { int common = gcd (Math.abs(numerator), denominator);
return num1; } }
numerator = numerator / common; denominator = denominator / common; }
37
38
}
//******************************************************************** // RationalTester.java // // Driver to exercise the use of multiple Rational objects. //******************************************************************** public class RationalTester { //----------------------------------------------------------------// Creates some rational number objects and performs various // operations on them. //----------------------------------------------------------------public static void main (String[] args) { RationalNumber r1 = new RationalNumber (6, 8); RationalNumber r2 = new RationalNumber (1, 3); RationalNumber r3, r4, r5, r6, r7;
r4 r5 r6 r7
= = = =
r1.add(r2); r1.subtract(r2); r1.multiply(r2); r1.divide(r2);
System.out.println System.out.println System.out.println System.out.println
("r1 ("r1 ("r1 ("r1
+ * /
r2: r2: r2: r2:
" " " "
+ + + +
r4); r5); r6); r7);
} }
System.out.println ("First rational number: " + r1); System.out.println ("Second rational number: " + r2); if (r1.equals(r2)) System.out.println ("r1 and r2 are equal."); else System.out.println ("r1 and r2 are NOT equal."); r3 = r1.reciprocal(); System.out.println ("The reciprocal of r1 is: " + r3);
39
40
10
aggregatie - aggregation
aggregatie - aggregation
een aggregatie object
voorbeeld 5:
is samengesteld uit andere objecten
een Student object is gedeeltelijk samengesteld uit Address objecten
een aggregatie is een heeft-een realtie
een student heeft twee adressen
vb: een auto heeft een chassis
in software:
zie StudentBody.java zie Student.java zie Address.java
een aggregatie object bevat referenties aan andere objecten een aggregatie object is gedeeltelijk gedefinieerd door de andere objecten die er deel van uitmaken
een aggregatie wordt in een UML klasse diagram met een open ruit aan het einde van de aggregatie
41
42
//******************************************************************** // Address.java // // Represents a street address. //******************************************************************** //----------------------------------------------------------------// Returns a description of this Address object. //----------------------------------------------------------------public String toString() { String result;
public class Address { private String streetAddress, city, state; private long zipCode; //----------------------------------------------------------------// Constructor: Sets up this address with the specified data. //----------------------------------------------------------------public Address (String street, String town, String st, long zip) { streetAddress = street; city = town; state = st; zipCode = zip; }
result = streetAddress + "\n"; result += city + ", " + state + "
" + zipCode;
return result; } }
43
44
11
//******************************************************************** // Student.java // // Represents a college student. //********************************************************************
//----------------------------------------------------------------// Returns a string description of this Student object. //----------------------------------------------------------------public String toString() { String result;
public class Student { private String firstName, lastName; private Address homeAddress, schoolAddress;
result = firstName + " " + lastName + "\n"; result += "Home Address:\n" + homeAddress + "\n"; result += "School Address:\n" + schoolAddress;
//----------------------------------------------------------------// Constructor: Sets up this student with the specified values. //----------------------------------------------------------------public Student (String first, String last, Address home, Address school) { firstName = first; lastName = last; homeAddress = home; schoolAddress = school; }
return result; } }
45
//******************************************************************** // StudentBody.java // // Demonstrates the use of an aggregate class. //********************************************************************
46
aggregatie in UML
public class StudentBody { //----------------------------------------------------------------// Creates some Address and Student objects and prints them. //----------------------------------------------------------------public static void main (String[] args) { Address school = new Address ("800 Lancaster Ave.", "Villanova", "PA", 19085);
StudentBody + main (args : String[ ]) : void
Student - firstName : String - lastName : String - homeAddress : Address - schoolAddress : Address + toString() : String
Address jHome = new Address ("21 Jump Street", "Lynchburg", "VA", 24551); Student john = new Student ("John", "Smith", jHome, school);
Address - streetAddress : String - city : String - state : String - zipCode : long
Address mHome = new Address ("123 Main Street", "Euclid", "OH", 44132); Student marsha = new Student ("Marsha", "Jones", mHome, school);
+ toString() : String System.out.println (john); System.out.println (); System.out.println (marsha); } } 47
48
12
de this referentie
de this referentie
de this referentie laat toe aan een object om naar zichzelf te verwijzen gebruikt binnen een methode, verwijst this naar het object waarvan de methode wordt uitgevoerd
voorbeeld:
de this referentie kan gebruikt worden om het onderscheid te maken tussen instantievariabelen en van een klasse en methode parameters met dezelfde naam
vb: de constructor van de klasse Account kan ook als volgt geschreven worden:
obj1.tryMe(); obj2.tryMe();
public Account (Sring name, long acctNumber, double balance) { this.name = name; this.acctNumber = acctNumber; this.balance = balance; }
in de eerste aanroep wordt met de this referentie verwezen naar obj1; in de tweede naar object obj2
49
objecten als parameters voor methoden
objecten als parameters voor methoden
de parameterbinding in een Java methode gebeurt: door het doorgeven van de waarde: “by value”
wat in een methode gebeurt met een parameter kan al of niet een effect hebben buiten de methode
een kopie van het argument (uit de aanroep) wordt geplaatst in de parameter (in de methode hoofding)
voorbeeld van gebruik van parameters: zie ParameterTester.java zie ParameterModifier.java zie Num.java
= vergelijkbaar met een toekenning
50
wanneer een object aan een methode wordt doorgegeven, worden argument en parameter aliasen van elkaar
51
noteer het verschil tussen het wijzigen van de referentie en het wijzigen van het object waaraan gerefereerd wordt.
52
13
//******************************************************************** // ParameterTester.java // // Demonstrates the effects of passing various types of parameters. //********************************************************************
//******************************************************************** // Num.java // Represents a single integer as an object. //******************************************************************** class Num { private int value;
public class ParameterTester { //----------------------------------------------------------------// Sets up three variables (one primitive and two objects) to // serve as actual parameters to the changeValues method. Prints // their values before and after calling the method. //----------------------------------------------------------------public static void main (String[] args) { ParameterModifier modifier = new ParameterModifier();
//----------------------------------------------------------------// Sets up the new Num object, storing an initial value. //----------------------------------------------------------------public Num (int update) { value = update; } //----------------------------------------------------------------// Sets the stored value to the newly specified value. //----------------------------------------------------------------public void setValue (int update) { value = update; } //----------------------------------------------------------------// Returns the stored integer value as a string. //----------------------------------------------------------------public String toString () { return value + ""; }
int a1 = 111; Num a2 = new Num (222); Num a3 = new Num (333); System.out.println ("Before calling changeValues:\n"); System.out.println ("a1\ta2\ta3"); System.out.println (a1 + "\t" + a2 + "\t" + a3 + "\n"); modifier.changeValues (a1, a2, a3); System.out.println ("After calling changeValues:\n"); System.out.println ("a1\ta2\ta3"); System.out.println (a1 + "\t" + a2 + "\t" + a3 + "\n"); 53
}
//******************************************************************** // ParameterModifier.java // // Demonstrates the effects of changing parameter values. //********************************************************************
}
54
}
vóór de aanroep van changeValues
a1
public class ParameterModifier { //----------------------------------------------------------------// Modifies the parameters, printing their values before and // after making the changes. //----------------------------------------------------------------public void changeValues (int f1, Num f2, Num f3) { System.out.println ("Before changing the values:\n"); System.out.println ("f1\tf2\tf3"); System.out.println (f1 + "\t" + f2 + "\t" + f3 + "\n");
111 int a1 = 111; Num a2 = new Num (222); Num a3 = new Num (333);
a2
222
a3
333
f1 = 999; f2.setValue(888); f3 = new Num (777); System.out.println ("After changing the values:\n"); System.out.println ("f1\tf2\tf3"); System.out.println (f1 + "\t" + f2 + "\t" + f3 + "\n"); } }
55
56
14
tester.changeValues ( a1, a2, a3 ) ;
a1
111
111
f1 = 999 ;
a1
f1
999
111
f1
tester.changeValues (a1, a2, a3); a2
222
f2
a2
222
f2
a3
333
f3
a3
333
f3
public void changeValues (int f1, Num f2, Num f3)
f1 = 999;
57
f2.setValue ( 888 ) ;
a1
f3 = new Num ( 777 ) ;
999
111
58
f1
a1
999
111
f1
a2
888
f2
a2
888
f2
a3
333
f3
a3
333
f3
777 f2.setValue(888); f3 = new Num (777);
59
60
15
terugkeer na changeValues
a1
111
a2
888
a3
333
61
16