Title: Chapter 9 : Interfaces
1Chapter 9 Interfaces
2Modeling alternative implementations
- Nim game implementation models class Player
responsible for making a move according to Game
rules. - Strategies Player can implement when making a
move - Timid strategy
- Greedy strategy
- Clever strategy
3Modeling alternative implementations
- Player abstraction and Player clients should be
- independent of implementations
- independent of strategies chosen
- implementations must respect the abstractions
contractPlayer makes a move according to Game
rules.
4Java interfaces
- A Java interface is used to specify minimal
functionality that a client requires of a server. - A Java interface contains
- method specifications, called abstract methods,
and - named constant definitions.
- A Java interface does not contain
- constructors,
- method bodies,
- instance variables.
5Player interface
- interface Player
- public String name ()
-
- public int sticksTaken ()
-
- public void takeTurn (Pile pile, int
maxOnATurn)
6Java interfaces
- An interface can be
- public , or
- package private.
- Method specifications in an interface are by
default - public, and
- abstract (only specification with no
implementation).
7Java interface implementation
- A class implements an interface by
- naming interface in an implements clause in class
heading, - and
- including definitions for all methods in
interface.
class TimidPlayer implements Player public
String name () public int sticksTaken ()
public void takeTurn (Pile pile, int
maxOnATurn)
8Java interface implementation
- Static diagram display of relation between
interface Player and class TimidPlayer
9Java interface
- Interface Player abstracts TimidPlayer,
GreedyPlayer, and CleverPlayer
interface
Player
is-a
is-a
GreedyPlayer
CleverPlayer
TimidPlayer
10Interface and types
- An interface defines a type.
- A value is in the interface type if it references
an instance of a class that implements the
interface. - A value of type reference-to-TimidPlayer, is also
of type reference-to-Player. - A value of type reference-to-GreedyPlayer, is
also of type reference-to-Player. - A value of type reference-to-CleverPlayer is also
of type reference-to-Player.
11Interface and types
- The type reference-to-TimidPlayer is said to be a
subtype of the type reference-to-Player. - The type reference-to-GreedyPlayer is said to be
a subtype of the type reference-to-Player. - The type reference-to-CleverPlayer is said to be
a subtype of the type reference-to-Player.
12Interface and types
- Reference-to-Player is a supertype of
- reference-to-TimidPlayer.
- reference-to-GreadyPlayer.
- reference-to-CleverPlayer.
- Simplify terminology refer to reference types by
class or interface name. Thus we say type
Player rather than type reference-to-Player.
13Interfaces and types
- A type defined by an interface can be used like
any other reference type. - It can be the type of an instance variable or
parameter, - It can be the return type of a query.
14Interfaces and typesRewriting Game
- Can define class Game exactly as in Listing 8.3,
even if Player is an interface and not a
class. - Instance variables can be of type Player
private Player player1 private player player2
- constructors and methods can have Player
parameters
public Game (Player player1, Player player2, int
sticks)
- queries can return values of type Player
public Player nextPlayer ()
15Types and Subtypes
- If client expects server of type Player, then a
value of any Player subtype can be provided. - Subtype rules
- if type A is a subtype of type B, then
- an A value can be provided wherever a B value is
required. - an A expression can be writtenwherever a B value
is required. - Thus for Game constructor
- It can be specified with parameters of type
Player interface - It can be invoked with arguments referencing
TimidPlayers, GreedyPlayers, CleverPlayers.
16Static types
- The Game method nextPlayer is specified as
public Player nextPlayer () The Player whose turn
is next.
- If game is a Game instance, Player is the static
type of expression
game.nextPlayer()
17Dynamic types
- When game.nextPlayer() is evaluated during
execution, value returned will reference an
specific object - If an instance of TimidPlayer. Then dynamic type
of value returned by expression is TimidPlayer. - If an instance of GreedyPlayer. Then dynamic type
of value returned by expression is GreedyPlayer. - If an instance of CleverPlayer. Then dynamic type
of value returned by the expression is
CleverPlayer. - The dynamic type is always a subtype of Player.
18Types and Subtypes
private Player nextPlayer private void
reportPlay (Player player) public Player winner
()
- The following require expressions of type Player
nextPlayer Player expression required reportPl
ay( Player expression required) public Player
winner () return Player expression
required
19Types and Subtypes
TimidPlayer timid new TimidPlayer("Wakko")
nextPlayer timid reportPlay(timid) public
Player winner () return timid
20Types and Subtypes
- If game is a Game instance, we cannot write the
following
TimidPlayer next game.nextPlayer()
- Assignment operator requires a TimidPlayer on
the right. - game.nextPlayer() is of type Player, and
- Player is not a subtype of TimidPlayer.
21Types and Subtypes
- Player p1
- Player p2
- TimidPlayer tp new TimidPlayer("Wakko")
- CleverPlayer cp new CleverPlayer("Guy")
p1 tp
p2 cp
p2 p1
22Types and Subtypes
- The following are not legal
tp p1 // p1 is not of type TimidPlayer cp
p2 // p2 is not of type CleverPlayer cp
tp // tp is not of type CleverPlayer
23Revised Nim game
- Classes Pile and Game remain the same.
- Game constructors, methods, and instance
variables are written in terms of type Player. - NimTUI will still have instance variables of type
Player
private Player player1 private Player player2
- Initialization code will create specific kinds
of players.
public NimTUI () this.player1 new
TimidPlayer("Player1") this.player2 new
GreedyPlayer("Player2") this.game
null this.in new Scanner(System.in)
24Nim game component relationships
25Implementing classes and contracts
Client
interface requires this
interface promises this
server accepts this
server delivers this
Server
server class can be more conservative in
server class can be more liberal in
what it accepts (weaker preconditions)
what it delivers (stronger postconditions)
than what is specified by the interface
than what is specified by the interface
26Interface Movable
27Interface Weapon
interface
wields
Explorer
Weapon
Pen
MissileLauncher
Sword
28Multiple inheritance of interfaces
class Sword implements Weapon, Movable
29Interface extension
- Assume all weapons are movable
interface Weapon extends Movable
30Extending more than 1 interface
- An interface can extend more than one interface.
interface DataIO extends DataInput, DataOutput
31Modifying Nim user vs. computer
- Want same simple nim game and text-based user
interface - Want user to play against the computer rather
than just watching the game. - need two different kinds of players.
- One player decides its own move
- the other gets its move from an external source,
the user.
32Modifying Nim user vs. computer
- Define two classes
- IndependentPlayer, and
- InteractivePlayer.
- Both classes implement interface Player.
- IndependentPlayer is specified exactly as the
class Player was in Chapter 8. - The InteractivePlayer, gets its move from a
client.
33Interactive player specifications
- class InteractivePlayer implements Player
- A player in the game simple nim that gets moves
from a client. - public InteractivePlayer (String name)
- Create a new InteractivePlayer with specified
name. - ensure this.name().equals(name)
- public String name ()
- This InteractivePlayers name.
- public int sticksTaken ()
- Number of sticks removed on this
InteractivePlayer's most recent turn. Returns 0
if this InteractivePlayer has not yet taken a
turn. - ensure this.sticksTaken() gt 0
34Interactive player specifications
- public void setNumberToTake (int number)
- Set number of sticks this InteractivePlayer
takes on its next turn. - require number gt 0
- public void takeTurn (Pile pile, int maxOnATurn)
- Take a turn remove sticks from specified Pile.
maxOnATurn is maximum number of sticks a Player
can remove on a turn. - require pile.sticks() gt 0, maxOnATurn gt 0
- ensure 1 lt this.sticksTaken()
- this.sticksTaken() lt maxOnATurn
- pile.sticks() old.pile.sticks() -
this.sticksTaken()
35Interactive player specifications
- User interface must also be modified. It creates
an InteractivePlayer and a IndependentPlayer
private InteractivePlayer user private
IndependentPlayer computer public NimTUI ()
this.user new InteractivePlayer("user")
this.computer new IndependentPlayer("computer")
this.game null this.in new
Scanner(System.in)
36Modifying User interface
- Added a parameter to playGame indicating whether
user wants to play first.
private void playGame (int numberOfSticks,
boolean userPlaysFirst) if
(userPlaysFirst) game new Game (user,
computer,numberOfSticks) else game new Game
(computer,user, numberOfSticks) while
(!game.gameOver()) game.play()
reportPlay(game.previousPlayer())
reportWinner(game.winner())
37User interface model interaction
- How does user interface know when to get a play
from user? - user interface checks whose turn it is before
invoking play - Need add a conditional to play loop,
while (!game.gameOver()) if (game.nextPlayer().
equals(user)) int numberToTake
readNumberToTake() user.setNumberToTake(numberT
oTake) game.play() reportPlay(game.previous
Player())
- readNumberToTake is similar to readNumberOfSticks.
38User interface model interaction
- Problem user interface is more involved in play
of the game. -
- Want dumb user interface, as isolated from
model as possible. - Role of the user interface is to manage input and
output its knowledge about how the model works
should be minimized. - This alternative makes the user interface the
model driver.
39User interface model interaction
- InteractivePlayer tells user interface it needs a
move. - This alternative requires that model be client to
user interface. - Dont want model dependent on user interface.
- User interface is properly client to model.
- Common User interface (client) needs to know
that model (server) has reached a state in which
it needs input from user. - InteractivePlayer
- must know the user interface.
- needs to notify an object when it is about to
make a move.
40InteractivePlayer
41Interface PlayerController
interface PlayerObserver Models an object that
needs to be informed when a InteractivePlayer is
about to make a play. public void update
(InteractivePlayer player) The specified
InteractivePlayer is making a play.
- Before removing sticks from pile,
InteractivePlayer notifies InteractiveController
by invoking update.
public void takeTurn (Pile pile, int maxOnATurn)
controller.update(this)
42Case interactive player takes turn
43Completing InteractivePlayer
- How InteractivePlayer know PlayerObserver?
- Add one more method to InteractivePlayer
public void register (PlayerObserver control) Set
PlayerObserver this InteractivePlayer reports
to. This InteractivePlayer will notify it before
taking its turn.
interface
notifies
InteractivePlayer
PlayerObserver
providesMoves
PlayerController
44TUIController and Game
- TUIController must know maximum number of sticks
that can be removed on users turn. - Add the following method to the Game
/ The maximum number of sticks that can be
removed on the next turn. Returns 0 if the
game is over. / public int maxOnThisTurn ()
if (pile.sticks() lt MAX_ON_A_TURN) return
pile.sticks() else return MAX_ON_A_TURN
45NimTUI playGame
- TUIController is by the NimTUI when Game is
created
private void playGame (int numberOfSticks, boolea
n userPlaysFirst) if (userPlaysFirst) game
new Game (user, computer, numberOfSticks) els
e game new Game (computer, user, numberOfSt
icks) new PlayerController(user, game,
in) while (!game.gameOver()) game.play()
reportPlay(game.previousPlayer()) reportWinne
r(game.winner())
46The strategy pattern
- Looking player classes, note duplicated code.
- Only difference in TimidPlayer, GreedyPlayer, and
CleverPlayer is body of takeTurn. - Duplicate code is a prime cause of maintenance
headaches, avoid when possible. - Can reduce duplicate code in player classes.
47The strategy pattern
- make Player a class and give Player a component
that determines what move to make.
- A Player will have an instance variable
referencing a PlayStrategy
private PlayStrategy strategy
48Strategy pattern
- takeTurn delegates responsibility for determining
how many sticks to take to PlayStrategy
public void takeTurn (Pile pile, int maxOnATurn)
int number strategy.numberToTake(pile,
maxOnATurn) pile.remove(number)
sticksTaken number
49Strategy pattern
- PlayStrategy is an interface that can be
implemented in various ways.
50Strategy pattern
- We can implement TimidStrategy
class TimidStrategy implements PlayStrategy
public void numberToTake (Pile pile, int
maxOnATurn) return 1
51Strategy pattern
- The easiest way to equip a Player with a
PlayStrategy is to provide one as a constructor
argument
public Player (String name, PlayStrategy
strategy) Create a Player with the specified name
and strategy
52Strategy pattern
- Players strategy can be changed dynamically.
- Players strategy is fixed when the Player is
created to be either a TimidPlayer, GreedyPlayer,
or CleverPlayer. - Include method to change Players strategy
public void setStrategy (PlayStrategy
strategy) Set this Players strategy to the one
specified.
- Ability to dynamically change objects behavior
is one reasons for using strategy pattern.
53Extra slides Java in Detail
54Casting
- Given variable definitions
Player player InteractivePlayer user
user player
- is not legal even if we write
Player player InteractivePlayer user new
InteractivePlayer("Louis") player user
//legal user player // not legal.
55Casting
- When certain of the dynamic type of a value, we
can cast the expression to this type
(type)expression
user (InteractivePlayer)player
- A cast to a supertype is always safe.
56Boolean operator instanceOf
- Boolean operator instanceof used to determine
type of value an expression produces at run-time.
expression instanceof type
- Returns true if expression evaluates to a value
of the specified type.
player instanceof InteractivePlayer
- Returns true if variable player references an
InteractivePlayer when expression is evaluated.