/*******************************************************************************
* Companion code for the book "Introduction to Software Design with Java",
* 2nd edition by Martin P. Robillard.
*
* Copyright (C) 2022 by Martin P. Robillard
*
* This code is licensed under a Creative Commons
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
*
* See http://creativecommons.org/licenses/by-nc-nd/4.0/
*
*******************************************************************************/
package e2.chapter7;
import java.util.Iterator;
/**
* A specialized Deck that stored a reference to
* all the cards drawn since the last shuffle.
*/
public class MemorizingDeck extends Deck {
private CardStack aDrawnCards = new CardStack();
/**
* @return The cards drawn.
*/
public Iterator<Card> getDrawnCards() {
return aDrawnCards.iterator();
}
@Override
public void shuffle() {
super.shuffle();
if( aDrawnCards != null ) {
aDrawnCards.clear();
}
}
@Override
public Card draw() {
Card card = super.draw();
aDrawnCards.push(card);
return card;
}
@Override
public MemorizingDeck clone()
{
MemorizingDeck clone = (MemorizingDeck) super.clone();
clone.aDrawnCards = new CardStack(aDrawnCards);
return clone;
}
}
Observe how the overridden version of the method adds to the behavior of the original. This is made explicit by the super call, which is then followed by additional statements.
Observe how the overridden version of the method adds to the behavior of the original. This is made explicit by the super call, which is then followed by additional statements.
The null check is necessary because of field initialization order.
Because the constructor of the superclass calls shuffle()
, the call
will also get dispatched down to this method when the constructor of Deck
is
executing. At that point, field aDrawnCards
is not yet initialized. If you
remove the null check, creating a new MemorizingDeck
will raise a NullPointerException
.
The null check is necessary because of field initialization order.
Because the constructor of the superclass calls shuffle()
, the call
will also get dispatched down to this method when the constructor of Deck
is
executing. At that point, field aDrawnCards
is not yet initialized. If you
remove the null check, creating a new MemorizingDeck
will raise a NullPointerException
.
Chapter 7, insight #9
You can use Java's cloning mechanism to implement polymorphic copying when the fields of the superclass are not accessible. However, cloning is a complex and error-prone mechanism that must be used very carefully
Chapter 7, insight #9
You can use Java's cloning mechanism to implement polymorphic copying when the fields of the superclass are not accessible. However, cloning is a complex and error-prone mechanism that must be used very carefully
Chapter 7, insight #5
Subclasses should be designed to complement, or specialize, the functionality provided by a base class, as opposed to redefining completely different behavior
Chapter 7, insight #5
Subclasses should be designed to complement, or specialize, the functionality provided by a base class, as opposed to redefining completely different behavior
Iterator
takes the place of
Enumeration
in the Java Collections Framework. Iterators
differ from enumerations in two ways:
Iterator
takes the place of
Enumeration
in the Java Collections Framework. Iterators
differ from enumerations in two ways:
This interface is a member of the Java Collections Framework.
Enumeration
can be converted into an Iterator
by
using the Enumeration.asIterator()
method.