1. Sample Class
    2. Objects represented as references
    3. Garbage Collection
    4. Self
    5. Arrays
    6. Information Hiding:
    7. Other method qualifiers
    8. Casts
    9. More examples:
Go back and discuss equal method.

Sample Class

// A playing card implementation 
public class Card implements CardInterface
{
    // "protected" means other classes can't access them 
    //  (data hiding)

    // instance variables
    protected int suit;     // The suit of card: CLUBS..SPADES
    protected int rank;     // The rank of the card: TWO..ACE
    ...

    // Methods
    public boolean equals(Object other)
    // pre:  other is a non-null CardInterface
    // post:  returns true iff this equals other
    {
        CardInterface otherCard = (CardInterface) other;
        // Cast required so can send getSuit & getRank messages.
        return (suit == otherCard.getSuit()) && 
                                            (rank == otherCard.getRank());
    }

    // Having this method allows Cards to be used in certain 
    // data structures. For now, just try to return different 
    // values for different cards. This returns a number in the 
    // range 0..51;  different cards yield different values
    public int hashCode()
    // post:  returns hash code for this card
    {
        return 13*suit + rank - 2;
    }
    
    ...

    // If a class contains a main method, 
    // that method can be run when the class is compiled
    // I always have one, which I use for testing the class
    public static void main(String args[])
    // Test Card class
    {
        // Create some cards
        CardInterface first = new Card(THREE,DIAMONDS);
        CardInterface second = new Card();
        
        System.out.println();
        System.out.println(first);
        System.out.println(second);
        System.out.println();
        
        // Note:  ! is the negation operator
        System.out.print("These cards are ");
        if(!first.equals(second))
            System.out.print("not ");
        System.out.println("equal");
        System.out.println();
        
        // Create an array of cards
        // Note syntax for array declaration
        CardInterface [] hand = new CardInterface[5];
        hand[0] = new Card(ACE,HEARTS);
        hand[1] = new Card(KING,HEARTS);
        hand[2] = new Card(QUEEN,HEARTS);
        hand[3] = new Card(JACK,HEARTS);
        hand[4] = new Card(TEN,HEARTS);
        
        // for loop
        // Note: declaration in for loop; 
        // ++ is the "add 1" operator
        for(int i=0;i<4;i++)
            System.out.print(hand[i] + ", ");
        
        System.out.println(hand[4]);
    }

}

Objects represented as references

Programs manipulate references to objects, rather than the objects themselves

like pointers.

Thus if

    firstCard = new Card(ACE,SPADES);
    secondCard = firstCard;
Then both refer to the same card. Assignment is sharing!

Objects initially have value null.

Can be given a value either by assignment (sharing) of an existing object or of a new constructor (as above)

Note that if x and y refer to objects then x==y iff x and y refer to the same object (i.e., doesn't matter whether their fields are the same).

Generally use equals method if want to know if the contents are the same.

    thirdCard = new Card(ACE,SPADES);
then thirdCard != firstCard, but thirdCard.equals(firstCard).

Garbage Collection

Need never dispose of objects!

Java is garbage collected: When can no longer access an object, space is reclaimed.


Self

Keyword "self" can be used in a method to refer to the object executing the method (i.e., the receiver of the message).

An object can send a message to itself by writing self.m(...) or just m(...) (self is assumed)

Similarly, can write self.suit or just suit to get access to an instance variable.

More interestingly, can send self as a parameter to another object.

Arrays

Arrays are objects and hence must be constructed.
    Card[] deck = new Card[52];
Creates 52 slots for cards, but all are currently null. Does not call Card constructor!

In program had to initialize individual slots:

deck[3] = new Card(TWO,DIAMONDS);

This invokes Card constructor.

Information Hiding:

Public: World has access to this feature

Protected: Features accessible within methods of the class (or extensions), but not accessible outside of the object.

All fields should be protected.

Thus firstCard.suit and firstCard.getSuitString() are undefined since both features declared to be protected.

Core Java tends to prefer private to protected. We'll generally use protected.

Private fields are not visible in extensions or outside object.

Protected and private declarations are used to hide implementation details from clients.

Makes it easier to change implementation later if needed.

Other method qualifiers

Static: One copy associated with the class - not associated with individual objects.

Typically get access through class or interface name, rather than object name:

    CardInterface.SPADES, CardInterface.ACE;
Final: May not be changed. Used to declare constants:
    static final int SPADES = 3;

Casts

Casts occasionally needed if static type of object not reflect actual type.

In equals only call with another CardInterface object, but type of parameter forced to be Object.

If cast is incorrect then program halts with error message.

More examples:

LottoHelper illustrates use of Random class.

Ratio gives another example of a class - fractions, this time.