Selection structures allow the computer to choose between alternative actions.
The methods that we have written thus far have a common characteristic--sequential execution. Sequential execution means that the statements are executed one after another in the order that they appear in the source code. In this chapter, we will learn how to create a block of statements that we can either execute or skip, as well as how we can choose to execute one of multiple alternative blocks of statements.
A control structure is a feature of a programming language that determines the order in which statements will be executed. There are three categories of control structures: (1) sequential structure, (2) selection structures, and (3) repetition structures (also called loops).
The sequential structure is the default structure that is used by most object-oriented programming languages. Unless we indicate otherwise, the statements will be executed in the order that they appear in the source code, and each statement will be executed exactly once each time a method is called. Every program that we have seen thus far uses nothing but the sequential structure.
A condition is a crucial part of the selection structures and the repetition structures. A condition is any expression that can be either true or false.
Every selection structure defines two or more alternate paths through the source code. There are three important selection structures: an if-then-else structure, an if-then structure, and a multi-way branching structure. An if-then-else structure (sometimes called an if-else structure) is the most fundamental selection structure, since it can be used to form any choice pattern possible. An if-then-else structure defines two different blocks of statements, only one of which will be executed. An if-then structure (sometimes called simply an if structure) is a special form of if-then-else where only one block of statements is provided and the second block of statements is omitted. As a result, an if-then structure defines an optional block of statements, where the block is either executed or skipped. A multi-way-if structure (sometimes called a multi-way branching structure) defines several different blocks of statements, only one of which will be executed. Java also has a switch structure to create a multi-way branching structure, but we'll learn about it later.
An if-then-else structure (sometimes called an if-else structure) defines two different blocks of statements, only one of which will be executed. An if-else structure consists of three parts, the selection condition, the true branch, and the false branch. The true branch contains a block of statements that will be executed whenever the selection condition is true. The false branch contains a block of statements that will be executed whenever the selection condition is false.
The figure above illustrates the generic if-then-else structure and uses arrows to show the order in which statements are executed and the condition is checked. The if-then-else structure defines a choice between two courses of action, only one of which will be executed.
The Jeroo
class provides a number of sensor
methods that can be used to ask a Jeroo something
about its immediate surroundings. Each sensor method has either a
true or a false result. Any method that produces either true or false
as a result is called a
boolean
method (also
called a predicate). More
generally, any expression that is either true or false is called a
boolean
expression (named after
George Boole).
This means that the conditions that are used in various control
structures are, in fact, boolean
expressions.
For Jeroos, the sensor methods are the basic building blocks for
creating conditions. The simplest way to create a condition is to
invoke a sensor method. The table below lists all of the sensor
methods provided by the Jeroo
class. These methods can
only be used to construct conditions. Since they are methods, they are
invoked by sending a message to a Jeroo
object.
Method | Purpose | Example |
---|---|---|
hasFlower() |
Does this Jeroo have any flowers? | dean.hasFlower() |
isClear(relativeDirection) |
Is there a clear space in the indicated direction? A clear
space contains no flower, no net, no water, and no Jeroo.
[isClear(HERE) is meaningless] |
dean.isClear(LEFT) dean.isClear(AHEAD) dean.isClear(RIGHT) |
isFacing(compassDirection) |
Is this Jeroo facing in the indicated direction? | dean.isFacing(NORTH) dean.isFacing(EAST) dean.isFacing(SOUTH) dean.isFacing(WEST) |
seesFlower(relativeDirection) |
Is there a flower in the indicated direction? | dean.seesFlower(HERE) dean.seesFlower(LEFT) dean.seesFlower(AHEAD) dean.seesFlower(RIGHT) |
seesJeroo(relativeDirection) |
Is there another Jeroo in the indicated direction?
[seesJeroo(HERE) is meaningless] |
dean.seesJeroo(LEFT) dean.seesJeroo(RIGHT) dean.seesJeroo(AHEAD) |
seesNet(relativeDirection) |
Is there a net in the indicated direction?
[seesNet(HERE) is meaningless] |
dean.seesNet(LEFT) dean.seesNet(AHEAD) dean.seesNet(RIGHT) |
seesWater(relativeDirection) |
Is there water in the indicated direction?
[seesWater(HERE) is meaningless] |
dean.seesWater(LEFT) dean.seesWater(AHEAD) dean.seesWater(RIGHT) |
This figure shows the syntax of the if-then-else structure in Java. There are four important things to observe about the syntax.
The condition must be in parentheses.
There is no semicolon after the parentheses.
There is no semicolon after the keyword
else
.
The if-then-else structure is not a method, which means that we do not send it as a message to a Jeroo object.
There are three important things to observe about the coding style.
Braces are used to define the beginning and end of both the true branch and the false branch. Always include them.
The braces are aligned with the start of the words
if
and else
.
The statements between the braces should be indented (we use 4 spaces).
Have the Jeroo named Timmy check for a net straight ahead. If there is one, have him disable it and turn around. If there is not a net straight ahead, Timmy should turn right. After he disables the net and turns around or simply turns right, Timmy must move one space forward.
if (timmy.seesNet(AHEAD)) { timmy.toss(); timmy.turn(LEFT); timmy.turn(LEFT); } else { timmy.turn(RIGHT); } timmy.hop();
An if-then structure (sometimes called an if structure) defines an optional block of statements. An if-then structure is simply an if-then-else structure where the second block of statements (the else part) has been omitted, so that the choice becomes whether to execute the first block of statements or skip it.
There are two parts to an if structure, the selection condition and the true branch. The true branch contains a block of statements that will only be executed whenever the selection condition is true.
The figure above shows a generic if-then structure, and uses arrows to show the order in which statements will be executed. The if structure defines optional code, and that code is either skipped or executed just once.
This figure shows the syntax of the if-then structure in Java. There are three important things to observe about the syntax.
The condition must be in parentheses.
There is no semicolon after the parentheses.
The if-then structure is not a method, which means that we do not send it as a message to a Jeroo object.
There are three important things to observe about the coding style.
Braces are used to define the beginning and end of the true branch. Always include them.
The braces are aligned with the start of the word
if
.
The statements between the braces should be indented (we use 4 spaces).
Have the Jeroo named Jessica check for a net to her right. If there is one, have her disable it and return to her current state. Whether or not she disables a net, Jessica should hop one space ahead.
if (jessica.seesNet(RIGHT)) { jessica.turn(RIGHT); jessica.toss(); jessica.turn(LEFT); } jessica.hop();
This figure shows a common technique for writing a multi-way selection structure in Java. Technically, this structure consists of a series of nested if-then-else statements, but the coding style obscures this fact and makes the multi-way selection logic more visible. This particular structure is often called a cascaded if.
There are five important things to observe about this structure.
Each condition must be in parentheses.
There is no semicolon after the parentheses.
There is no limit on the number of else-if blocks.
The final else
branch is optional.
This structure is not a method, which means that we do not send it as a message to a Jeroo object.
There are three important things to observe about the coding style.
Braces are used to define the beginning and end of each branch. Always include them.
The braces are aligned with the start of the words
if
and else
.
The statements between the braces should be indented (we use 4 spaces).
Assume that a Jeroo named Louisa is carrying at least one flower. Have her check the cell ahead. If that cell contains a flower, pick it. If that cell contains a net, disable it. If that cell contains water, plant a flower at the current location. If that cell contains another Jeroo, give that Jeroo a flower. Finally, if there is nothing in that cell, have her hop once and turn left.
if (louisa.seesFlower(AHEAD)) { louisa.hop(); louisa.pick(); } else if (louisa.seesNet(AHEAD)) { louisa.toss(); } else if (louisa.seesWater(AHEAD)) { louisa.plant(); } else if (louisa.seesJeroo(AHEAD)) { louisa.give(AHEAD); } else { louisa.hop(); louisa.turn(LEFT); }
Conditions come in two forms, simple and compound.
A simple condition is a boolean
expression that does not
contain any other boolean
expression. With Jeroos, a
simple condition is formed by invoking a single sensor method. A
compound condition is created by
using logical operators to combine conditions. The three most commonly
used logical operators in Java are: negation (not), conjunction (and),
and disjunction (or). Java uses special keystrokes for each of these as
shown in the following table.
Operator | Java Symbol | Meaning |
---|---|---|
Negation | ! (exclamation point) |
NOT |
Conjunction | && (2 keystrokes; no
space between) | AND |
Disjunction | || (2 keystrokes; no space
between) | OR |
The negation reverses the value of a boolean
expression,
changing true to false and false to true, as shown in this table:
P | !P |
---|---|
true | false |
false | true |
In this table, P represents an arbitrary boolean
expression. The two rows underneath P show its
possible values. The second column shows the corresponding values for
the expression !P, where the negation operator is applied
to the boolean
expression.
The conjunction operator (&&
, representing
logical AND) combines two boolean
expressions to create a third that is
only true when both of the original expressions are true:
P | Q | P && Q |
---|---|---|
true | true | true |
true | false | false |
false | true | false |
false | false | false |
In this table, P and Q represent
arbitrary boolean
expressions. The rows underneath P
and Q show all possible combinations of their values.
The third column shows the corresponding values for
P && Q
.
The disjunction operator (||
, representing logical OR)
combines two boolean
expressions to create a third that is only false
when both of the original expressions are false:
P | Q | P || Q |
---|---|---|
true | true | true |
true | false | true |
false | true | true |
false | false | false |
In this table, P and Q once again
represent arbitrary boolean
expressions. The rows underneath
P and Q show all possible combinations
of their values. The third column shows the corresponding values for
the expression P || Q
.
Remember that these are expressions that could be either true or false. They are not statements of fact.
Boolean Expression (Java-style) | English Translation |
---|---|
!bob.seesNet(AHEAD) |
There is not a net ahead of Bob |
bob.hasFlower() && bob.isClear(LEFT) |
Bob has at least one flower and there is nothing in the cell immediately to the left of Bob. |
bob.seesWater(AHEAD) || bob.seesWater(RIGHT) |
There is water ahead of Bob or to the right of Bob, or both |
bob.isFacing(WEST) &&(!bob.seesNet(AHEAD)) |
Bob is facing west and there is no net ahead |