Classes and Methods

static methods

The Java construct for implementing functions is known as the static method.

Methods

  • Multiple arguments – methods can take on more than one argument, and therefore can have more than one parameter variable
  • Overloading – methods whose signatures differ are different methods. Using the same name for two methods whose signatures differ is known as overloading.
  • Single return value – A Java method provides only one return value to the caller, of the type declared in the method signature

Methods

  • Scope – The scope of a variable is the part of the program that can refer to that variable by name. The scope of a variable declared in a method is limited to that method’s body. You cannot refer to a variable in one method that is declared in another.

Source: Programming in Java, Sedgewick & Wayne (2024)

Constructors

Same name as the class, no return type

Public vs. Private

public – accessible from all methods of the class and in the scope of where the object is declared

private – known only in the class

Recommendations for writing classes

  • use one file to store the class (no main method)
  • create different classes for different problems (cohesion – methods and instance variables of a class should be strongly related) – in other words, keep related data and behavior in one place

Recommendations for writing classes

Declare:

  • instance variables private after class definition and create public methods to set and access variables
  • constructors public no return type (do not use static)
  • most methods public (do not use static), but private helper methods are often useful

Example

public class IdentifyMyParts {
    public int x = 7; 
    public int y = 3; 
}
  1. What are the instance variables?
  2. How do you construct a new instance of this class?

Exercise from The Java™ Tutorials

Example

public class IdentifyMyParts {
    public int x = 7; 
    public int y = 3; 
}

What is the output from the following code:

IdentifyMyParts a = new IdentifyMyParts();
IdentifyMyParts b = new IdentifyMyParts();
a.y = 5;
b.y = 6;
a.x = 1;
b.x = 2;
System.out.println("a.y = " + a.y);
System.out.println("b.y = " + b.y);
System.out.println("a.x = " + a.x);
System.out.println("b.x = " + b.x);
System.out.println("IdentifyMyParts.x = " + IdentifyMyParts.x);

Add static after public for one of the instance variable (to make it a class variable). What is the side effect?

Better example

public class IdentifyMyParts {
    private int x = 7;
    private int y = 3;
    
    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }
    
    public int getX() {
        return x;
    }
    
    public int getY() {
        return y;
    }

}

Variable scope: what’s the difference between this.x and x?

Better example – use

public class UseMyParts {

    public static void main(String[] args) {
        IdentifyMyParts a = new IdentifyMyParts(); 
        IdentifyMyParts b = new IdentifyMyParts(); 
        a.setX(5);
        a.setY(10);
        b.setX(2);
        b.setY(3);
    
        System.out.println(a.getY()); 
        System.out.println(b.getY()); 
        System.out.println(a.getX()); 
        System.out.println(b.getX()); 

    }
}

Adding a constructor method

public class IdentifyMyParts {
    private int x = 7;
    private int y = 3;
    
    public IdentifyMyParts(int x, int y) {
        this.x = x;
        this.y = y;
        
    }
    
    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }
    
    public int getX() {
        return x;
    }
    
    public int getY() {
        return y;
    }

}

Practice – Card class

A card has a suit and a rank

Suits The four suits are clubs (♣), diamonds (♦), hearts (♥), and spades (♠).

Ranks The ranks are ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, jack, queen, and king. The ace is the highest card, and the 2 is the lowest, but the ace can also be used as a low card with a value of 1.

Card class solution

public class Card {
    private String rank;
    private String suit;
    
    public Card(String rank, String suit) {
        this.rank = rank;
        this.suit = suit;
    }
    
    public String getSuit() {
        return suit;
    }
    
    public String getRank() {
        return rank;
    }

}

Write main

Create a PlayGame class with a main method to create an instance of a card and to print it.

What changes to Card class would you make?

Solution

public class PlayGame {

    public static void main(String[] args) {
        Card card1 = new Card("ace", "hearts");
        card1.print();
    }

}

And add a method to Card:

public void print() {
        System.out.println(rank + " of " + suit);
    }

Update Card class (demonstration)

  • validate suit and rank – make sure the object is created with valid strings only
  • create constants for arrays of strings for both suits and ranks
  • create helper methods (private) for validation
  • two ways of setting rank: integer and string (overloading)

Update Card class – solution

public class Card {
    private String rank;
    private String suit;
    
    private final static String[] RANKS = {"ace", "two", "three", "four",
                                           "five", "six", "seven",
                                           "eight", "nine", "ten",
                                           "jack", "queen", "king"};

    
    public final static String[] SUITS = {"diamonds", "clubs", "hearts", "spades"};
    
    public Card(String rank, String suit) {
        if (validRank(rank)) this.rank = rank;
        if (validSuit(suit)) this.suit = suit;
    }
    
    public Card(int rank, String suit) {
        if (rank >= 1 && rank <= 13) this.rank = RANKS[rank-1];
        if (validSuit(suit)) this.suit = suit;
    }

    private Boolean inArray(String value, String[] arr) {
        for (String element : arr) {
            if (element.equals(value)) return true;
        }
        return false;
    }
    
    private Boolean validRank(String rank) {
        return inArray(rank, RANKS);
    }
    
    private Boolean validSuit(String suit) {
        return inArray(suit, SUITS);
    }
    
    
    public void setRank(String rank) {
        if (validRank(rank)) this.rank = rank;
    }
    
    public void setRank(int rank) { // overloading
        if (rank >= 1 && rank <= 13) this.rank = RANKS[rank-1];
    }
    
    public void setSuit(String suit) {
        if (validSuit(suit)) this.suit = suit;
    }
    
    public String getSuit() {
        return suit;
    }
    
    public String getRank() {
        return rank;
    }
    
    public void print() {
        System.out.println(rank + " of " + suit);
    }

}

Update PlayGame class

public class PlayGame {

    public static void main(String[] args) {
        Card card1 = new Card("ace", "hearts");
        card1.print();
        
        card1.setRank(2);
        card1.print();
        
        Card card2 = new Card(13, "diamonds");
        card2.print();

    }

}

Create Deck class

Create a Deck class that has a color, and all 52 possible cards (use ArrayList)

Deck class solution

import java.util.ArrayList;

public class Deck {
    private ArrayList<Card> cards = new ArrayList<Card>();
    private String color;
    
    public Deck(String color) {
        this.color = color;
        for (String s : Card.SUITS) {
            for (int i = 1; i <= 13; i++) {
                Card thisCard = new Card(i, s);
                cards.add(thisCard);
            }
            
        }
    }
    
    public void print() {
        for (int i = 0; i < cards.size(); i++) {
            String thisSuit = cards.get(i).getSuit();
            String thisRank = cards.get(i).getRank();
            System.out.println(thisRank + " of " + thisSuit);
        }
    }
    
    public Card getCard(int index) {
        return cards.get(index);
    }
    
    public String getColor() {
        return color;
    }

}

Updated PlayGame

public class PlayGame {

    public static void main(String[] args) {
        Card card1 = new Card("ace", "hearts");
        card1.print();
        
        card1.setRank(2);
        card1.print();
        
        Card card2 = new Card(13, "diamonds");
        card2.print();
        
        Deck myDeck = new Deck("Red");
        myDeck.printCards();
        
        myDeck.getCard(20).print();

    }

}

Using Random

import java.util.Random;

Use the Random class to draw a random card from myDeck

// create instance of Random class
Random rand = new Random();
   
// Generate random integers in range 0 to 51
int cardIndex = rand.nextInt(52);

enum

An enum type is a special data type that enables for a variable to be a set of predefined constants

  public enum suitOptions {
        DIAMONDS, HEARTS, SPADES, CLUBS;
        
    }
    
    private suitOptions suit;
    
    // constructor
    public Card(suitOptions suit, String rank) {
        this.suit = suit;
        this.rank = rank;
    }

Example of usage:

Card cardOne = new Card(Card.suitOptions.DIAMONDS, "ace");

enum

Read documentation