Title: Chapter 9 : Interfaces
1Chapter 9 Interfaces
2Objectives
- After studying this chapter you should understand
the following - the role of abstraction in the specification of a
server - the use of interfaces to specify servers
independent of implementation details - the notion of subtype, and fundamental property
of a subtype - contractual requirements in the implementation of
an interface - multiple inheritance of interfaces
- the notion and use of the strategy pattern.
- Also, you should be able to
- specify and implement an interface
- use an interface to capture commonality among
similar classes.
3Modeling 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
4Modeling 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.
5Java 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.
6Player interface
- interface Player
- public String name ()
-
- public int sticksTaken ()
-
- public void takeTurn (Pile pile, int
maxOnATurn)
7Java 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).
8Java interface implementation
- A class implements an interface by
- naming interface in an implements clause in class
heading, - and
- including definitions for all methods in the
interface.
9Java interface implementation
- class TimidPlayer implements Player
- public String name ()
-
- public int sticksTaken ()
-
- public void takeTurn (Pile pile, int maxOnATurn)
-
10Java interface implementation
- Static diagram display of relation between
interface Player and class TimidPlayer
11Java interface
- Interface Player abstracts TimidPlayer,
GreedyPlayer, and CleverPlayer
12Interface 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.
13Interface 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.
14Interface and types
- Reference-to-Player is a supertype of
- reference-to-TimidPlayer.
- reference-to-GreadyPlayer.
- reference-to-CleverPlayer.
15Terminology
- Simplify terminology refer to reference types by
class or interface name. Thus we say type
Player rather than type reference-to-Player.
16Interfaces 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.
17Interfaces 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 ()
18Types 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.
19Types and Subtypes
- Thus for Game constructor
- It can be specified with parameters of type
Player interface - it can be invoked with arguments referencing
TimidPlayers, GreedyPlayers, CleverPlayers.
20Static 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()
21Dynamic 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.
22Types 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
23Types and Subtypes
TimidPlayer timid new TimidPlayer("Wakko")
nextPlayer timid reportPlay(timid) public
Player winner () return timid
24Types 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.
25Types and Subtypes
- Player p1
- Player p2
- TimidPlayer tp new TimidPlayer("Wakko")
- CleverPlayer cp new CleverPlayer("Guy")
p1 tp
p1 tp
p2 cp
p2 p1
26Types 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
27Revised 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
28Revised Nim game
- 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 BasicFileReader()
29Implementing 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
30Interface Movable
31Interface Weapon
interface
wields
Explorer
Weapon
Pen
MissileLauncher
Sword
32Multiple inheritance of interfaces
class Sword implements Weapon, Movable
33Interface extension
- Assume all weapons are movable
interface Weapon extends Movable
34Extending more than 1 interface
- An interface can extend more than one interface.
- interface DataIO extends DataInput, DataOutput
35Modifying 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.
36Modifying Nim user vs. computer
- need two different kinds of players.
- One player decides its own move
- the other gets its move from an external source,
the user.
37Modifying 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.
38Interactive 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 the
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
39Interactive 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()
40Interactive 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") thi
s.computer new IndependentPlayer("computer") t
his.game null this.in new
BasicFileReader()
41Modifying 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()) reportWinne
r(game.winner())
42User 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 the 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.
43User 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.
44User interface model interaction
- InteractivePlayer tells user interface it needs a
move. - This alternative requires that model be client to
user interface. - Dont want the model dependent on user
interface. User interface is properly client to
the model. - Common client needs to know that server has
reached some particular state. - User interface (client) needs to know that model
(server) has reached a state in which it needs
input from the user.
45User interface model interaction
- InteractivePlayer must know the user interface.
- InteractivePlayer needs to notify an object when
it is about to make a move.
46Interface InteractiveController
- interface InteractiveController
- 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.
47Interface InteractiveController
- Before removing sticks from pile,
InteractivePlayer notifies InteractiveController
by invoking update.
public void takeTurn (Pile pile, int maxOnATurn)
controller.update(this)
48Case interactive player takes turn
49Completing InteractivePlayer
- How does the InteractivePlayer know the
InteractiveController? - Add one more method to InteractivePlayer
public void register (InteractiveController
control) Set InteractiveController this
InteractivePlayer is to report to. This
InteractivePlayer will notify it before taking
its turn.
50Class TUIController
51TUIController 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
52NimTUI 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 TUIController(user,game,in) while
(!game.gameOver()) game.play() reportPlay(g
ame.previousPlayer()) reportWinner(game.winne
r())
53The 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.
54The strategy pattern
- make Player a class and give Player a component
that determines what move to make.
55Strategy pattern
- A Player will have an instance variable
referencing a PlayStrategy,
private PlayStrategy strategy
56Strategy 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
57Strategy pattern
- PlayStrategy is an interface that can be
implemented in various ways.
58Strategy pattern
- We can implement TimidStrategy
class TimidStrategy implements PlayStrategy
public void numberToTake (Pile pile, int
maxOnATurn) return 1
59Strategy 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
60Strategy 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.
61Casting
- 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.
62Casting
- 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.
63Boolean 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.
64Summary
- Introduced the fundamental notion of interface
- It captures functional requirements of a server.
- Similar to a class, but includes no
implementation. - It is not instantiated to produce objects.
- To implement an interface, a class names
interface in an implements clause, and implement
all methods specifies. - Many concrete classes can implement an interface.
65Summary
- Also introduced the notion of subtyping
- If class C implements an interface I, reference
type defined by C is a subtype of type defined by
I. - An expression of type C can be written in any
context requiring I. - If a client requires services defined by
interface I, an instance of class C can provide
those services.
66Summary
- Javas type conformance rules are static
verified by the compiler from the program text. - If A is a supertype of B, e1 is an expression of
type A, e2 an expression of type B - Can write e2 in a context requiring a B value.
- Cannot write e in a context requiring a B value
- If certain that evaluating e delivers a B value
at run-time, must cast e1 to the appropriate
type (B)e1. - If not certain that e1 delivers a B value, can
guard cast by using the operator instanceof.
67Summary
- Studied situation in which a client needs to know
when a server reaches some state. (The observer
pattern). - The client informs the server of its interest by
invoking a server method (register). - To keep the server as independent as possible
from the client, the server knows the client
through a minimal interface. - When the server reaches the relevant state, it
informs the client by invoking a client method
(update). - An example is the InteractivePlayer and
InteractiveController
68Summary
- Studied a second situation in which some behavior
of an object is encapsulated in a component. - The component is defined by an interface, and the
objects behavior can be changed dynamically by
replacing the component. - This is referred to as the strategy pattern, and
was illustrated in the player-with-strategy
example.