Session 7: Defining an object

The Account class (Section 3.3)
    What data is associated with an object?
    What actions can we perform on the object?
Using Account
    A one-account bank
    A more complex bank
Constructor methods (Section 3.4)
Quiz 1

The Account class

Textbook: Section 3.3

Ok, so how do we define our own type?

Let's do an example: We're going to create a type called Account to represent a bank account. (Think of this object definition as being part of a much larger banking system.)

To design our object, we ask ourselves two questions.

What data is associated with an object?

In the case of a bank account, one important piece of data is the balance - the amount of money currently in the account. You can imagine other pieces of data too (like maybe the account's owner), but actually in our example for the moment we'll just have the balance.

To define an Account type containing this piece of data, we would write the following into a file called Account.java.

import csbsju.cs160.*;

public class Account {
    private double balance;

    public Account() {
        balance = 0.0;
    }
}
Notice that we declared the balance field to be a double type, and to be private. We declared it private because we don't want other people to go around messing with balance without using one of our officially sanctioned methods that we're about to define here in a minute.

See how we omitted the static keyword when we declared the instance variable? We'll see this when we get to methods also: the static keyword indicates that the member is a class member instead of a instance member (the default, if you don't say static). So you'd use the static keyword if the variable were a class variable - but you'll omit it if you want an instance variable.

The second part - which looks mysteriously like a method definition - is called the constructor method. It's purpose is to initialize the fields of Account to appropriate first values. In this case, it sets the balance value to start at 0.0.

What actions can we perform on the object?

So what can we do to a bank account?

  1. We can query it to get the current balance.
  2. We can deposit money into it.
  3. We can withdraw money from it.
And so we'll define three methods as part of our class definition, specifying how to perform each of these actions.

import csbsju.cs160.*;

public class Account {
    private double balance;

    public Account() {
        balance = 0.0;
    }

    public double getBalance() {
        return balance;
    }

    public void deposit(double amount) {
        balance += amount;
    }

    public void withdraw(double amount) {
        balance -= amount;
    }
}

These are quite similar to the methods we defined earlier, except that you'll notice that they don't contain the word static. These are instance methods, whereas the static methods we've used heretofore were class methods. Instance methods apply only to particular objects (instances) of type Account (which have associated with them a balance field). The static methods were associated with the class, not with particular objects of that class.

You'll notice that we've defined the methods to be public. That's because we want to allow other people to employ these methods in order to manipulate an Account object.

Using Account

A one-account bank

Using the Account class we've defined, we can now put together a complete program using this Account object we created. We're going to create an additional class called VerySimpleBank - to allow us to work with a bank for which there is only one account. This class would be placed into a separate file, called VerySimpleBank.java.

import csbsju.cs160.*;

public class VerySimpleBank {
    public static void run() {
        Account mine = new Account();
        while(true) {
            IO.print("Balance: ");
            IO.println(mine.getBalance());
            IO.print("Deposit? ");
            mine.deposit(IO.readDouble());
        }
    }
}

A more complex bank

A one-account bank isn't very realistic. Instead, let's make a program that works with two accounts!

import csbsju.cs160.*;

public class SimpleBank {
    public static void run() {
        Account mine = new Account();
        Account yours = new Account();
        while(true) {
            Account a;
            IO.print("Which account? ");
            if(IO.readInt() == 0) a = mine;
            else                  a = yours;

            IO.print("Balance: ");
            IO.println(a.getBalance());
            IO.print("Deposit? ");
            a.deposit(IO.readDouble());
        }
    }
}
In this program, we've added a new account (yours). And we've added some code at the beginning of the loop, allowing the user to choose which account to work with in that iteration.

If we ran this program, we'd see the following.

Which account? 0       we select my account
Balance: 0.0             my account has $0 so far
Deposit? 5000
Which account? 1       we select your account
Balance: 0.0             your account has $0 so far
Deposit? 3
Which account? 0       we select my account
Balance: 5000.0          my account has $5000 so far
 : and so on

Constructor methods

Textbook: Section 3.4

When you use the new keyword to create a new object instance, the computer goes through a three-step process.

  1. First it clears out space in memory for holding the data associated with an Account. In this case, this entails making room for the 64 bits associated with the balance field (since balance is a double). If there were other instance variables, space for them would be allocated too.

  2. Then it enters the constructor function for the created object, which initializes the fields of the object (setting balance to be 0.0, in this case).

  3. Finally, it returns the location in memory where Account was placed, so that (in this case) mine can refer to this particular object just created and initialized.

Remember this: The job of a constructor method is to initialize the instance variables of a new instance.. We saw this in our Account definition, where the constructor method sets the initial balance to zero.

Sometimes we want to be able to provide additional data about how to set up a new object. To do this, we can add parameters to our constructor function.

For example, when we create a new account, we might want to initialize it with an initial balance. To do this, we'll have one parameter to our constructor, specifying the initial balance.

public class Account {
    private double balance;

    public Account(double initial) {
        balance = initial;
    }
}
Now, when we create a new account, we have to provide an argument, telling the constructor function what to use for the value of the initial parameter.
Account mine = new Account(1527.21);
This creates for me a new account containing $1,527.21.

Sometimes we might have multiple constructor functions, for different combinations of parameters.

public class Account {
    private double balance;

    public Account() {
        balance = 0.0;
    }
    public Account(double initial) {
        balance = initial;
    }
}
This gives the programmer using the class a choice of ways to create an object. Java will determine which constructor function the programmer has chosen based on the number and types of parameters listed when creating the object.
Account yours = new Account();
Account mine = new Account(1527.21);
In this case, the first line refers to the first constructor function (with no parameters) - it creates your account with an initial balance of $0.00. The second line refers to the second constructor function and creates my account with an initial balance of $1,527.21. Creating multiple constructor methods like this is called overloading the constructor method.

Quiz 1