Download Chapter 4 : Conditionals

Document related concepts
no text concepts found
Transcript
An Introduction to
Programming and Object
Oriented Design using Java
3rd Edition. Dec 2007
Jaime Niño
Frederick Hosch
Chapter 4 : Conditionals
Postconditions and invariants
 Method currentCount in Counter is specified as
/**
* The number of items counted.
*/
public int currentCount () { …
 Can be more precise : integer result is non-negative.
/**
* The number of items counted.
* @ensure this.currentCount() >= 0
*/
public int currentCount () { …
 Postcondition: condition that implementor promises will
be satisfied when method completes execution.
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
1
Postconditions and invariants
 Make sure instance variable count >= 0 always.
 Document this via a class invariant:
private int count;
// current count
// invariant: count >= 0
 A class invariant will always be true of all instances of
the class.
 If we add decrementCount to Counter:
public void decrementCount ()
Decrement positive count by 1;
zero count remains zero.
 In implementation, need to add guard to be sure not to
decrement when count == 0
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
2
The if-then statement
if (condition)
statement
B E G IN
true
condition
false
statement
E N D
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
3
Implemeting decrementCount
/**
* Decrement positive count by 1;
* zero count remains zero
*/
public void decrementCount () {
if (count > 0)
count = count - 1;
}
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
4
Explorer: invariants and guards
 Restrict Explorer’s tolerance to be a non-negative integer.
private int tolerance;
// current tolerance
// invariant: tolerance >= 0
/**
* Annoyance (hit points) required to defeat
* this Explorer.
*
* @ensure tolerance >= 0
*/
public int tolerance () {
return tolerance;
}
 Need to insure value assigned in each case is not negative.
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
5
Explorer: invariants and guards
 Consider method takeThat.
 Need to guard the two statements:
if (annoyance <= tolerance)
tolerance = tolerance - annoyance;
if (annoyance > tolerance)
tolerance = 0;
 But, only one of those should execute when invoking
takeThat.
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
6
if-then-else statement
if (condition)
statement1
else
statement2
B E G IN
true
false
condition
statement
statement
2
1
E N D
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
7
Implementing method takeThat
public void takeThat (int annoyance) {
if (annoyance <= tolerance)
tolerance = tolerance - annoyance;
else
tolerance = 0;
}
Implementing constructor
public Explorer (String name, Room location,
int strength, int tolerance) {
…
if (tolerance >= 0)
this.tolerance = tolerance;
else
this.tolerance = 0;
…
}
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
8
Compound statements
if (condition) {
statement1
…
statementN
}
Dec 2007
if (condition) {
statement11
…
statement1N
} else {
statement21
…
statement2M
}
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
9
Conditions: boolean expressions
 Boolean expressions:
 Produce boolean values when evaluated;
 Evaluate to true or false.
 Can declare boolean variables, and assign values:
private boolean tooBig;
 And can assign values to it:
tooBig = true;
Or
tooBig = size > 10;
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
10
Handling multiple cases
 A conditional statement divides problem into two cases
to be considered independently.
 In many problems, there are more than two cases, or
cases need to be further divided into subcases.
 Use nesting conditional statements.
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
11
Handling multiple cases
 Assume class Date with properties day, month,year.
 Implement a Date’s query that will tell whether or not a
date occurs in a leap year.
public boolean isLeapYear ()
This Date occurs in a leap year.
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
12
Handling multiple cases
isLeapYear
Case: year not
divisible by 4
not a leap year.
Case: year divisible by 4
???
Case: divisible by 100
Case: not divisible
by 100
is leap
???
Case: divisible Case: not divisible by 400
by 400
is not leap
is leap
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
13
Handling multiple cases
// This Date occurs in a leap year.
public boolean isLeapYear () {
boolean aLeapYear;
if (year % 4 == 0)
if (year % 100 == 0)
// divisible by 100,
// must also be divisible by 400
aLeapYear = (year % 400 == 0);
else // divisible by 4, not by 100
aLeapYear = true;
else // not divisible by 4
aLeapYear = false;
return aLeapYear;
}
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
14
Cascading conditionals
 When problem splits into more than two cases:
 “cascade” if-then-else statements.
if (case1)
handleCase1
else if (case2)
handleCase2
…
else if (penultimateCase)
handlePenultimateCase
else
handleLastCase
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
15
TrafficLight’s change() method
change
:
case: light is GREEN
change to YELLOW
Dec 2007
case: light is YELLOW
change to RED
case: light is RED
change to GREEN
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
16
TrafficLight’s change() method
public void change () {
if (light == GREEN)
light = YELLOW;
else if (light == YELLOW)
light = RED;
else // light == RED
light = GREEN;
}
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
17
Dangling else
 There is an ambiguity with the structure
if (condition1)
if (condition2)
statement1
else
statement2
if (condition1)
if (condition2)
statement1
else
statement2
Dec 2007
What if does else go with?
if (condition1)
if (condition2)
statement1
else
statement2
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
18
Dangling else
B E GIN
false
condition1
B E GI N
true
condition1
true
condition2
statement2
true
false
false
statement1
statement2
condition2
true
statement1
false
E ND
Dec 2007
E ND
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
19
Dangling else: equivalent statements
if (condition1)
if (condition2)
statement1
else
statement2
if (condition1) {
if (condition2)
statement1
else
statement2
}
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
20
Class Date: method nextDate()
public Date nextDate ()
The Date following this Date.
nextDate:
case: last day of the year
year = this.year + 1
month = 1
day = 1
case: not last day of the year
case: last day of a month
year = this.year
month = this.month + 1
day = 1
case: not last day of a month
year = this.year
month = this.month
day = this.day + 1
Auxilary methods:
private boolean isLastDayOfYear ()
This Date is the last day of a year.
private boolean isLastDayOfMonth ()
This Date is the last day of a month.
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
21
Class Date: method nextDate()
public Date nextDate () {
int day, month, year;
if (isLastDayOfYear()) {
year = this.year + 1;
month = 1;
day = 1;
} else
if (isLastDayOfMonth()) {
year = this.year;
month = this.month + 1;
day = 1;
} else {
year = this.year;
month = this.month;
day = this.day + 1;
}
return new Date(year,month,day);
}
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
22
Class date: method isLastDayOfMonth()
isLastDayOfMonth
case: month is February
case: month has 30 days
day == 30
case: month has 31 days
day == 31
case: leap year case: not leap year
day == 28
day == 29
Need to write method is30DaysMonth():
private boolean is30DayMonth () {
return month == 4 || month == 6 || month == 9 ||
month == 11;
}
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
23
Class Date: constructor precondition
/**
* Create a new Date.
* Arguments day, month, year must represent
* a legal calendar date. year must be > 1752.
*/
public Date (int day, int month, int year)
 Need to provide client a method to determine whether
or not constructor arguments represent a legal date.
 Method is not a feature of a Date instance, but a utility
of the Date class.
public static boolean isLegalDate (
int day, int month, int year)
Arguments day, month, year represent
a legal calendar date.
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
24
Extra material
Java in detail
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
25
Relational operators
<=
>
>=
==
!=
less than or equal
greater than
greater than or equal
equal (A single ‘=‘ denotes assignment.)
not equal
 A relational expression consists of two expressions
joined with a relational operator.
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
26
Relational expressions: Examples
 Let i1=10, i2=-20, i3=30.
i1 < 12
 true
i1 <= 10
 true
i3 == i1
 false
i1 != 2
 true
i1 < 10
 false
i2 > 0
 false
2*i1 == i2+40
 true
i2*(-1) != i1+i1
 false
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
27
Relational expressions
 An expression like a<b<c is illegal.
 int values are converted to double, in mixed type
comparisons:
10 > 2.5  10.0 > 2.5  false
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
28
Relational expressions
 floating point values are approximations for real
numbers, avoid using equality or inequality operators
with them.
(1.0/6.0 + 1.0/6.0 + 1.0/6.0 +
1.0/6.0 + 1.0/6.0 + 1.0/6.0) == 1.0  false
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
29
Reference equality and object equality
 Operators == and != can be used to compare values of
any type.
 Comparing reference values must be of same type.
Counter counter1;
Counter counter2;
Explorer myHero;
counter1 == counter2 // legal
counter1 == myHero
Dec 2007
// compilation error
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
30
Reference equality and object equality
 Two reference values are equal if they refer to same object.
 How to check if two different objects are equal?
 If string1, string2, and string3 are String variables,
string1 = "c";
string2 = "ab" + string1;
string3 = "a" + "bc";
 string2 and string3 will reference two distinct objects.
string2 == string3  false
 use String method equals,
string2.equals(string3)  true
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
31
Boolean operators
!
&&
||
not
and
or
 Use :
! booleanExpression
booleanExpression && booleanExpression
booleanExpression || booleanExpression
 A boolean expression evaluates to true or false
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
32
The ! (not) operator
 “Not” reverses boolean values.
!true  false
!false  true
 Given : i1=10;
!( i1 > 9)  !(true)  false
 Beware: “Not” has high precedence.
! i1 > 9  (!i1) > 9  illegal
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
33
&&, || (and then, or else)
operators
Given: i1=10;
(i1>10)||(i1==10)
(i1>10)||(i1<0)
(i1>0)&&(i1<5)
(i1>0)&&(i1<20)
Dec 2007




false || true  true
false || false  false
true && false  false
true && true  true
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
34
&&, || (and then, or else) operators
 && and || have lower precedence than the relational
operators.
 Parentheses are still useful as they enhance readability.
i1 < i2 && i1 < i3 means
(i1 < i2) && (i1 < i3)
 Using the “and then” operator, can express the condition
that value of i1 is between 0 and 20:
(0 < i1) && (i1 < 20)
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
35
The && and || are lazy operators
 They evaluate only the left operand only when that suffices.
 Given i1=10;
(i1 < 10) && (i1 > 0)  false && (i1 > 0)  false
(i1 < 11) || (i1 > 100) true || (i1 > 100) true
 Right operands, (i1 > 0) and (i1 > 100), are not evaluated.
 Useful
when
considering
expressions
like
(x == 0) || (y/x < 10)
 If left operand is true, x is 0, evaluating right operand will
result in an attempt to divide by 0 and a run-time error.
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
36
Operator precedence
High
unary +, unary -,
*, /, %
+, <, <=, >, >=
==, !=
&&
||
!
Low
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
37
DeMorgan’s Laws
 Useful for simplifying expressions.
!(b1 && b2)  !b1 || !b2
!(b1 || b2)  !b1 && !b2
!(i1>5 && i1<8)  !(i1>5) || !(i1<8)
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
38
Extra slides material
Combination lock
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
39
Example: combination lock
 Responsibilities:
 Know:
The combination
whether unlocked or locked
 Do:
lock
unlock
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
40
CombinationLock class
 Class: CombinationLock
 Queries:
 is open
 Commands:
 lock
 unlock
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
41
Class CombinationLock specifications
public class CombinationLock
Contructor:
public CombinationLock (int combination)
Queries:
public boolean isOpen()
Commands:
public void close ()
public void open(int combination)
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
42
Class CombinationLock implementation
Component variables:
private int combination;
private boolean isOpen;
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
43
Structure for a simple test
public class CombinationLock {
private int combination;
private boolean isOpen;
public CombinationLock (int combination) {
}
public boolean isOpen () {
return true;
}
public void close () {
}
}
Dec 2007
public void open (int combinationToTry) {
}
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
44
Structure for a simple test
class CombinationLockTest {
private CombinationLock lock;
public CombinationLockTest () {
}
}
public void runTest () {
}
public class TestCombinationLock {
public static void main (String[] argv) {
(new CombinationLockTest()).runTest();
}
}
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
45
Precondition
 A condition client of a method must make sure holds
when method is invoked.
 “Require”s : Constructor and method enter have
requirements that clients must meet for them to execute
properly.
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
46
Constructor specifications
/**
* Create a lock with the specified combination.
*
* @require:
*
0 <= combination && combination <= 999
* @ensure:
*
this.isOpen()
*/
public CombinationLock (int combination) …
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
47
Testing locks
 Need method to create and test lock with given combination:
private void testLock (int combination)
Test a lock with the specified combination.
 Invoke this method in runTest for each lock to test.
public void runTest () {
testLock(0);
testLock(123);
testLock(999);
}
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
48
Automating checking of test results
private void verify (boolean test, String message) {
if (!test)
System.out.println(
"Verification failed: " + message);
}
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
49
testLock method
 testLock method must create lock and run initial state
test:
private void testLock (int combination) {
lock = new CombinationLock(combination);
testInitialState();
}
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
50
testLock method
 Initial state test should make sure that lock is open.
 So, instead of writing the test method:
private void testInitialState() {
System.out.println("Initial state: " +
lock.isOpen());
}
 Write:
private void testInitialState() {
verify(lock.isOpen(), "initial state");
}
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
51
Class CombinationLock implementation
 The straightforward implementations:
public CombinationLock (int combination) {
this.combination = combination;
this.isOpen = true;
}
public boolean isOpen () {
return isOpen;
}
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
52
Class CombinationLock implementation
 In constructor, there are two variables with same name.
 Component variable and
 local variable combination.
 this.combination refers to component variable.
 If variable does not include object reference this in
front of it, it is a reference to local variable.
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
53
Class CombinationLock implementation
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
54
Method to test close
 write method to test close, and invoke it from
testLock:
private void testClose() {
lock.close();
verify(!lock.isOpen(), "close open lock");
lock.close();
verify(!lock.isOpen(), "close closed lock");
}
private void testLock (int combination) {
lock = new CombinationLock(combination);
testInitialState();
testClose();
}
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
55
Implementing close in Lock
 Command close is also easy to implement:
public void close () {
isOpen = false;
}
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
56
Method to test open
 Test for the method open: four cases to test:
closed lock, correct combination: lock opens;
open lock, correct combination: lock remains open;
closed lock, incorrect combination: lock remains
closed.
open lock, incorrect combination: lock remains
open;
 Test depends on combination, so pass correct combination
as argument:
private void testOpen (int combination)
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
57
testOpen method
private void testOpen (int combination) {
int badCombination = (combination + 1) % 1000;
// test with correct combination:
lock.close();
lock.open(combination); // open closed lock
verify(lock.isOpen(), "open closed lock");
lock.open(combination); // open opened lock
verify(lock.isOpen(), "open opened lock");
}
// test with incorrect combination:
lock.open(badCombination); // try opened lock
verify(lock.isOpen(), "bad comb, opened lock");
lock.close();
lock.open(badCombination); // try closed lock
verify(!lock.isOpen(), "bad comb, closed lock");
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
58
testOpen method
 Add an invocation of this method to testLock:
private void testLock (int combination) {
lock = new CombinationLock(combination);
testInitialState();
testClose();
testOpen(combination);
}
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
59
Method open implementation
 The following implementation of open fails the tests.
public void open (int combination) {
isOpen = (this.combination == combination)
}
 test will produce the following output:
 Verification failed: bad comb, opened lock
 Verification failed: bad comb, opened lock
 Verification failed: bad comb, opened lock
 Root of problem: attempt to open an already opened
lock with incorrect combination should not close it.
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
60
Method open implementation
 Correct implementation of method uses a conditional
statement that opens the lock if the combination is
correct, and does nothing if the combination is not
correct:
public void open (int combinationToTry) {
if (this.combination == combinationToTry)
isOpen = true;
}
Dec 2007
NH-Chapter4: Introduction To Programming and Object
Oriented Design Using Java
61
Related documents