CS2514

Introduction to Java

Dr Derek Bridge

School of Computer Science & Information Technology

University College Cork

Card.java

class Card {

    int rank;
    String suit;
    
    public Card(int r, String s) {
        rank = r;
        suit = s;
    }
    
    public boolean higher(Card c) {
        return rank > c.rank;
    }
    
    public boolean lower(Card c) {
        return rank < c.rank;
    }
    
    public String toString() {
        return rank + " of " + suit;
    }
    
}

Deck.java (Version A)

import java.util.Random;

class Deck {

    Card[] cards;
    
    public Deck() {
        String[] suits = {"Clubs", "Diamonds", "Hearts", "Spades"};
        cards = new Card[52];
        int indexOfNextCard = 0;
        for (int i = 0; i < suits.length; i = i + 1) {
            for (int j = 1; j < 14; j = j + 1) {
                cards[indexOfNextCard] = new Card(j, suits[i]);
                indexOfNextCard = indexOfNextCard + 1;
            }
        }
    }
    
    public void shuffle() {
        Random randy = new Random();
        for (int i = 0; i < cards.length; i = i + 1) {
            int j = randy.nextInt(cards.length);
            Card temp = cards[i];
            cards[i] = cards[j];
            cards[j] = temp;
        }
    }
    
    public Card deal() {
        Card c = cards[cards.length - 1];
        Card[] all_but_last = new Card[cards.length - 1];
        for (int i = 0; i < all_but_last.length; i= i + 1) {
            all_but_last[i] = cards[i];
        }
        cards = all_but_last;
        return c;
    }
}

Changing the implementation of Deck

Deck.java (Version C)

import java.util.Random;
class Deck {

    Card[] cards;
    int indexOfLastCard;
    
    public Deck() {
        String[] suits = {"Clubs", "Diamonds", "Hearts", "Spades"};
        cards = new Card[52];
        int indexOfNextCard = 0;
        for (int i = 0; i < suits.length; i = i + 1) {
            for (int j = 1; j < 14; j = j + 1) {
                cards[indexOfNextCard] = new Card(j, suits[i]);
                indexOfNextCard = indexOfNextCard + 1;
            }
        }
        indexOfLastCard = 51;
    }
    
    public void shuffle() {
        Random randy = new Random();
        for (int i = 0; i < indexOfLastCard + 1; i = i + 1) {
            int j = randy.nextInt(indexOfLastCard + 1);
            Card temp = cards[i];
            cards[i] = cards[j];
            cards[j] = temp;
        }
    }
    
    public Card deal() {
        Card c = cards[indexOfLastCard];
        indexOfLastCard = indexOfLastCard - 1;
        return c;
    }
}

Encapsulation

Game.java

import java.util.Scanner;
class Game {

    public void play() {
        Scanner sc = new Scanner(System.in);
        int score = 0;
        Deck d = new Deck();
        d.shuffle();
        Card currentCard = d.deal();
        for (int i = 0; i < 4; i = i + 1) {
            System.out.print("Will the next card be higher (H) or lower (L) than a " + currentCard + "? ");
            String guess = sc.nextLine();
            Card nextCard = d.deal();
            System.out.print("It's a " + nextCard + ". ");
            if ((guess.equals("L") && nextCard.lower(currentCard)) || (guess.equals("H") && nextCard.higher(currentCard))) {
                System.out.println("Yes!");
                score = score + 1;
            } else {
                System.out.println("Bad luck!");
            }
            currentCard = nextCard;
        }
        System.out.println("You scored " + score + " out of 4.");
    }
}

But we're not hiding enough!

Instance variables should be private

Instance variables: visibility

Visibility: summary

Visibility modifiers determine where variables can be accessed from

(From Coad, P., Mayfield, M. and Kern, J.: Java Design: Building Better Apps & Applets (2nd edn.), Yourdon Press, 1999)

What about instance methods?

Example without a helper method

class ATM {

    private String currency;
    private int[] denominations;
    private int[] contents;
    
    public ATM(String s, int[] denoms) {
        currency = s;
        denominations = denoms;
        contents = new int[denominations.length];
    }
    
    public String getCurrency() {
        return currency;
    }

    public int getTotal() {
        int total = 0;
        for (int i = 0; i < denominations.length; i++) {
            total = total + denominations[i] * contents[i];
        }
        return total;
    }
    
    public int getQty(int denom) {
        for (int i = 0; i < denominations.length; i++) {
            if (denominations[i] == denom) {
                return contents[i];
            }
        }
        return 0;
    }

    public String toString() {
        String s = "";
        for (int i = 0; i < denominations.length; i++) {
            s = s + contents[i] + " x " + currency + denominations[i] + "; " ;
        }
        return s;
    }

    public void load(int qty, int denom) {
        for (int i = 0; i < denominations.length; i++) {
            if (denominations[i] == denom) {
                contents[i] += qty;
                return;
            }
        }
    }

    public void dispense(int qty, int denom) {
        for (int i = 0; i < denominations.length; i++) {
            if (denominations[i] == denom && contents[i] >= qty) {
                contents[i] -= qty;
                return;
            }
        }
    }

}

Example with a helper method

class ATM {

    private String currency;
    private int[] denominations;
    private int[] contents;
    
    public ATM(String s, int[] denoms) {
        currency = s;
        denominations = denoms;
        contents = new int[denominations.length];
    }
    
    public String getCurrency() {
        return currency;
    }

    public int getTotal() {
        int total = 0;
        for (int i = 0; i < denominations.length; i++) {
            total = total + denominations[i] * contents[i];
        }
        return total;
    }
    
    public int getQty(int denom) {
        int posn = indexOf(denom);
        if (posn != -1) {
            return contents[posn];
        } else {
            return 0;
        }
    }

    public String toString() {
        String s = "";
        for (int i = 0; i < denominations.length; i++) {
            s = s + contents[i] + " x " + currency + denominations[i] + "; " ;
        }
        return s;
    }

    public void load(int qty, int denom) {
        int posn = indexOf(denom);
        if (posn != -1) {
            contents[posn] += qty;
        }
        // else no update
    }

    public void dispense(int qty, int denom) {
        int posn = indexOf(denom);
        if (posn != -1 && contents[posn] >= qty) {
            contents[posn] -= qty;
        }
        // else no update
    }

    private int indexOf(int denom) { 
        for (int i = 0; i < denominations.length; i++) {
            if (denominations[i] == denom) {
                return i;
            }
        }
        return -1;
    }
    
}

Design