Notes
Outline
Chapter 6
Conditions
This chapter discusses
Conditions and conditional statements.
Preconditions, postconditions, and class invariants.
Boolean expressions.
Conditions
postcondition: a condition the implementor (server) guarantees will hold when a method completes execution.
invariant: a condition that always holds true.
class invariant: an invariant regarding properties of class instances: that is, a condition that will always be true for all instances of a class.
Counter class
class invariant: component variable tally will always be greater than or equal to zero.
This holds true with the methods currently defined.
postcondition: the method count must make sure that tally is greater or equal to zero when the method completes execution.
Counter class (cont.)
Adding a method decrementCount threatens the class invariant constraint that tally be greater than or equal to zero.
public void decrementCount () {
tally = tally - 1;
}
We must guard the assignment statement with a condition statement.
Specifications
Postconditions and class invariants are part of class specification but not the implementation.  Therefore they should be included in comments but not in the implementation.
/**
 * Current count;the number of items
 * counted.
 * ensure:
 * count >= 0
 */
 public int count () { … }
Specifications (cont.)
private int tally; //current count
//invariant:
//  tally >= 0
if-then statement
Syntax: if (condition)   statement
A composite statement.
Counter class
/**
 *Decrement positive count by 1
 */
public void decrementCount () {
if (tally > 0)
tally = tally - 1;
}
Explorer Class
/**
 * Damage (hit points) required to defeat
 * this Explorer.
 *   ensure:
 * stamina >= 0
 */
public int stamina () {
return staminaPoints;
}
…
private int staminaPoints;//current stamina
//invariant: //staminaPoints >= 0
Explorer Class
If stamina reaches 0, an explorer is defeated.
One possible solution:
public void takeHit (int hitStrength){
if (hitStrength <= staminaPoints)
staminaPoints = staminaPoints -     hitStrength;
}
But this rarely lets the  staminaPoints reach zero.
Another possible approach
public void takeHit (int hitStrength){
if (hitStrength <= staminPoint)
staminaPoints = staminaPoints -     hitStrength;
if (hitstrength > staminaPoints)
staminaPoints = 0;
}
What is wrong with this approach?
Another possible approach (cont.)
It may meet the first condition and then in its changed state, meet the second condition as well.
If-then-else statement
Syntax: if (condition)   statement1     else   statement2
Explorer class
public Explorer(… , int stamina, …) { …
if (stamina >=0)
staminaPoints = stamina;
else
staminaPoints = 0; …
}
public void takeHit (int hitStrength){
if (hitStrength <= staminaPoints)
staminaPoints = staminaPoints -     hitStrength;
else
staminaPoints = 0;
}
Explorer constructor
What should we do if the constructor is called with a negative value for the parameter stamina?
public Explorer (String name, rooms.Room location, int hitStrength,
int stamina) { …
if (stamina >= 0)
staminaPoints = stamina;
else
staminaPoints = 0; …
}
Compound statements
Syntax: { statement1 statement2 … }
In this statement,
if (hitStrength <= staminaPoints)
staminaPoints = staminaPoints - hitStrength;
else
staminaPoints = 0;
strengthPoints = 0;
The last statement is not part of the else condition.
Compound statements (cont.)
Compound statements (cont.)
Braces are used to create a block or compound statement, which is a single composite statement.
if (condition) { if (condition) {
statement1    statement1
…    …
statementn    statementn
} } else {
   statement1
   …
   statementn
}
Compound statements (cont.)
if (hitStrength <= staminaPoints)
staminaPoints = staminaPoints - hitStrength;
else {
staminaPoints = 0;
strengthPoints = 0;
}
Relational expressions
Relational operators:
< less than
<= 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.
Relational expressions (cont.)
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
Relational expressions (cont.)
An expression like a<b<c is illegal.
If one operand is an int and the other is a double, the int is first converted to a double. 10 > 2.5 º 10.0 > 2.5
Since floating point values are approximations for real numbers, we should 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
Boolean variables
Booleans  can be stored as variables.
private boolean tooBig;
tooBig = true;
tooBig = i1 > 10;
Boolean operators
! not
&& and
|| or
! booleanExpression
booleanExpression && booleanExpression
booleanExpression || booleanExpression
A boolean expression evaluates to either true or false.
The “not” operator
“Not” reverses boolean values.    i.e. !true º false      !false º true
i1=10
!( i1 > 9) º !(true) º false
“Not” has high precedence.
! i1 > 9 º (!i1) > 9 º illegal
Generally avoid the “not” operator.
“And” and “or”
(i1>10)||(i1==10)ºfalse||trueºtrue
(i1>10)||(i1<0)ºfalse||falseºfalse
(i1>0)&&(i1<5)ºtrue&&falseºfalse
(i1>0)&&(i1<20)ºtrue&&trueºtrue
“And” and “or” (cont.)
The && and || have lower precedence than the relational operators, but parentheses are still useful because they enhance readability.
The && and || are lazy operators that evaluate only the left operand only when that suffices.
“And” and “or” (cont.)
Consider:
(5 == 4) && ????
(5 != 4) || ????
Does it matter what the second operands are?
This can protect against runtime errors such as an attempt to divide by zero.
Example: (x == 0) || (y/x < 10)
      (x != 0) && (y/x < 10)
DeMorgan’s laws
Useful for simplifying expressions.
!(b1 && b2) º !b1 || !b2
!(b1 || b2) º !b1 && !b2
!(i1>5 && i1<8) º !(i1>5) || !(i1<8)
Operation precedence
Handling multiple cases
Consider a method that determines if a year is a leap year.
The Gregorian calendar stipulates that a year is a leap year if it is divisible by 4, unless it is also divisible by 100, in which case it is a leap year if and only if it is divisible by 400. For example, 1900 is not a leap year, but 2000 is.
(year % 100 != 0 && year % 4 == 0) ||
(year % 100 == 0 && year % 400 == 0)
LeapYear method
Another way of representing these rules uses cases and nested conditional statements.
public boolean isLeapYear (int year) {
boolean aLeapYear;
if (year % 4 == 0)
if (year % 100 == 0)
aLeapYear = (year % 400 == 0);
else
aLeapYear = true;
else
aLeapYear = false;
return aLeapYear;
}
LeapYear method (cont.)
TrafficSignal class
The traffic signal class cycles through 4 states:
LEFT (left turn arrow)
 GO (green light)
CAUTION (yellow light)
 STOP (red light)
The component variable currentState will hold one of these states.
TrafficSignal class (cont.)
advance moves currentState to the next state.
public void advance () {
private int currentState;
if (currentState == LEFT)
currentState = GO;
else if (currentState == GO)
currentState = CAUTION;
else if (currentState == CAUTION)
currentState = STOP;
else //currentState == STOP
currentState = LEFT;
}
TrafficSignal class (cont.)
Dangling else
Which if statement is this else statement associated with?
if (condition1)
if (condition2)
statement1
else
statement2
Dangling else (cont.)
It is associated with the second if (B).
To associate it with the first, add braces around everything contained between the first if and the else.
if (condition1) {
if (condition2)
statement1
} else
statement2
Example: combination lock
Responsibilities:
Know:
The combination
whether unlocked or locked
Do:
lock
unlock
CombinationLock class
Class: CombinationLock
Queries:
is open
Commands:
lock
unlock
Class CombinationLock specifications
public class CombinationLock
Contructor:
public CombinationLock (int combination)
Queries:
public boolean isOpen()
Commands:
public void close ()
public void open(int combination)
Class CombinationLock implementation
Component variables:
private int  combination;
private boolean isOpen;
Class CombinationLock implementation (cont.)
The straightforward implementations:
public boolean isOpen () {
return isOpen;
}
public void close () {
isOpen = false;
}
Class CombinationLock implementation (cont.)
When the constructor is being executed, there are two distinct variables with the same name. (Component variable and local variable combination).
The keyword this refers to the “current object.” Therefore this.combination refers to the component variable.
If the variable does not include the object reference this in front of it, it is a reference to the local variable.
Class CombinationLock implementation (cont.)
Class CombinationLock implementation (cont.)
public CombinationLock (int combination) {
this.combination = combination;
isOpen = false;
}
We could write the second assignment as
this.isOpen = false;
But there is no ambiguity, so it is not needed.
Class CombinationLock implementation (cont.)
A final method:
public void open (int combination) {
if (this.combination == combination)
isOpen = true;
}
Digit by digit lock:
This lock has a 3 digit combination.
To open the lock, the client provides the digits one at a time.
If the client enters the three digits of the combination in order, the lock opens.
It doesn’t matter how many digits the client provides, as long as the combination is given.
Digit by digit lock: (cont.)
Digit Entered
4
1
2
4
3
1
2
3
Digit Entered
1
2
3
4
7
Class CombinationLock
public class CombinationLock
Constructor:
public CombinationLock (int combination)
require: combination >= 0 &&       combination <=999
Queries:
public boolean isOpen ()
Commands:
public void close ()
public void enter (int digit)
require:  digit >=0 && digit <=9
Precondition
A condition the client of a method must make sure holds when the method is invoked.
The constructor and method enter have certain requirements that must be met for them to execute properly.  These are the “require:”s found it the definition on the previous slide.
Somewhat like the “unleaded gas only” sign near the gas cap on an automobile.
CombinationLock responsibilities
Know:
the 3-digit combination.
whether locked or unlocked.
the last three digits entered.
Do:
lock.
unlock, when given the proper combination.
accept a digit.
Getting digits from integers.
Using the % and / operator, we can extract each digit.
Suppose a combination 123.
123 % 10 -> 3
123 / 10 -> 12
12 % 10 -> 2
12 / 10 -> 1
% 10 gets the last digit and / 10 get the remaining digits.
CombinationLock implementation
// entered1, entered2, entered3 are the last three
// digits entered, with entered3 the most recent.
// a value of -1 indicates the digit has not been
// entered.
private int entered1;
private int entered2;
private int entered3;
      // invariant:
      // entered1 >= -1 && entered1 <= 9 &&
      // entered2 >= -1 && entered2 <= 9 &&
      // entered3 >= -1 && entered3 <= 9
Slide 56
Slide 57
Slide 58
Slide 59
We’ve covered
Boolean expressions.
Conditional statements.
if (condition)
   statement
if (condition)
statement1
else
   statement2
Compound statements {statement1 statement2 … statementn}.
Preconditions, postconditions, invariants.
Glossary
Glossary (cont.)