Classes
If we only ever wanted to model games of dice, we'd be fine with primitives. But most games have game-state that is more complex. Let's start with a card game, like Poker. How do we model a playing card? A playing card has a suit—Spades, Hearts, Clubs, or Diamonds—and a rank—Ace, 2–10, Jack, Queen, and King. A real playing card has other attributes, such as decoration on the back of the card, but suit and rank are the only two that matter in a game.
The class mechanism allows us to model types that are collections of other types, where each element of the collection has a name. In the case of a card, the names of the elements are “suit” and “rank.” An element of a class is called a field.
Before we model a card, we need to know how we are going to model the suit and rank fields. Fortunately, we covered this in the previous section:
enum Suit { Spades, Hearts, Clubs, Diamonds }
enum Rank { Ace, R2, R3, R4, R5, R6, R7, R8, R9 , R10, Jack, Queen, King }
With these definitions of Suit and Rank, we can model a Card in this way:
class Card {
Suit suit;
Rank rank;
}
This is a class declaration. The general form is:
class class-name {
field-type field-name ;
[additional field declarations]
}
suit and rank are fields of class Card. For this particular class we used the same names for the fields as for the fields' types, except that the field names are not capitalized. In this case the convention that type names are capitalized and variable and field names are not capitalized was particularly convenient. Java is case-sensitive, so Suit and suit are not considered to be the same identifier. Therefore we could choose “Suit” for the name of the type and “suit” for the name of the field, and Java understands that they are two separate things.
Here's another example. A distance, such as the distance between two cities, consists of a numeric value, plus the units of the value. Here's how we might model that:
class Distance {
double value;
Units units;
}
enum Units { Kilometers, Miles }
A class's fields are fixed
The fields of a class are fixed at compile-time. You cannot add fields to your class when your program is running. This is an important feature of Java. Because of it, Java can check your code when it compiles it to make sure that it is not referring to fields that don't exist.
It would be useful to have a data type where you accessed its elements by name, and you could add new elements to it. Java has such a type, called Map, but it is considerable more complicated to use, and we do not discuss it here.