Second Summer 2002


Lecture Notes Nine: Classes, objects, constructors.
There is only one remaining issue with the BankAccount. We need to define the default constructor.

Why do we need to talk about the default constructor? Because that's the one we're using now, not having defined any constructor whatsoever yet.

Constructors are not methods, but they are used to create instances of the class (objects). Many classes have more than one constructor.

The purpose of a constructor is to initialize the instance variables of the object. The code for a constructor sets the initial state of the object.

When a BankAccount object comes into existence it will have an initial state with the current balance being 0 (zero). So there's just one constructor for the class.

Since it does not take any arguments it is called a no-arg constructor. Its purpose is to initialize the instance variables of a bank account object when the object is created.

Objects of type BankAccount only have one instance variable: their balance. If you do not initialize an instance variable that is a number it will automatically be initialized to 0 (zero) by Java, befor the constructor even comes into play.

In this regard, instance variables act differently than local variables! By local variables you mean "variables declared in methods, such as in main", right?

Yes. Those have to be initialized by the programmer before they are used. It's not the same with instance variables.

Instance variables are set by Java to a default value. Local variables will not.

No they won't be initialized by Java. Instance variables, however, will be initialized by Java if you don't initialize them (as a programmer). OK. If the balance of a new account will be set to 0 (zero) even before the constructor starts working, then the constructor need not do anything.

Yes. And Java will always provide (by default) a no-arg constructor that doesn't do anything, for every class that you define. So if you don't define any constructor you will be given one, by default.

Yes, and if you define at least one, those that you define are your constructors. How do we write a constructor?

They are essentially initialization procedures so they look very similar to methods. They have a header, and a method body. Their header contains an access specifier, but not a return type.

Their name is always that of the class. Like methods they have a list of parameters: named locations of a certain type, in which their initial information is placed.

That is, the arguments. Indeed. Can I see one?

Here's the one that you get by default, if you don't specify any constructor. It's the one in blue. Note that the body of the constructor is empty.
public class BankAccount {
  public BankAccount() {
    // nothing 
  }
  public void deposit(double amount) {
    balance = balance + amount; 
  }
  public void withdraw(double amount) { 
    balance = balance - amount;    
  }
  public double getBalance() { 
    return balance; 
  }
  private double balance; 
} 

Since this is the default constructor that means I get it for free. Indeed, but you might actually write it anyway to not forget that you can use it.

Can I define a second constructor? How would you want to use it?

I'd like to create an account with an initial sum of money in it, like this: Yes you can. You will only need to set balance to the initial value inside the constructor.
BankAccount m = new BankAccount(300.00); 

Is that it?
public BankAccount(double initial) {
  balance = initial; 
} 
Yes, can you describe it a little?

It is used to create a bank account with an initial balance. When you call it you need to specify that amount, like you did when you showed me the way you intended to use it.

A constructor looks like a method, only the header does not have a return type, and the name of a constructor is the name of the class. The rest of it is just like a method.

Yes, so I defined a formal parameter initial which must be of floating-point type (that is, with a fractional part). I chose double for the type of the formal parameter. So in your previous example this constructor gets called to create a new object, and the initialization steps start by storing 300.00 in a location of type double by the name initial.

Yes, and in its body I use initial to copy its value in balance. Very well. You could have used it in a more involved way, but there was no need for you to do that.

There's a tricky rule in Java about the default no-arg constructor. We mentioned it above, but in an implicit way.

We can avoid mentioning it here by stating another rule, that is easier to state (and remember). Always declare all the constructors that you need.

And how's the actual rule? The default constructor is provided by default when there are no constructors specified. If you specify at least one constructor, the default constructor no longer is provided and if you need it you need to write it explicitly in the class.

I see, so this class definition won't let me create bank accounts with an initial value of 0 (zero)? Not directly.
public class BankAccount {
  double balance; 
  public BankAccount(double initial) {
    balance = initial; 
  }
  
}

So I can't say
BankAccount m = new BankAccount(); 
No, but you can create it this way:
BankAccount m = new BankAccount(0.0); 

Well, can we put the class to work? Sure, we did that last time, we can do it again. Here's a different test program though:
public class BankAccountTest {
  public static void main(String[] args) {
    BankAccount account = new BankAccount(10000); 
    final double INTEREST_RATE = 5; 
    double interest;
    // compute and add interest for one period 
    interest = account.getBalance() * INTEREST_RATE / 100; 
    account.deposit(interest); 
    System.out.println("Balance after the first year is $" + 
                       account.getBalance()); 
    // add interest again 
    interest = account.getBalance() * INTEREST_RATE / 100; 
    account.deposit(interest); 
    System.out.println("Balance after the second year is $" + 
                       account.getBalance()); 
  } 
} 

And the class is still the same as last time, with the two constructors added, ... the no-arg empty constructor and the one that initializes the balance to a certain initial value, that is specified when you call the constructor.

Yes, here it is:
public class BankAccount { 
  private double balance; // instance variable, the account balance
  public BankAccount() { // the no-arg empty constructor

  } 
  public BankAccount(double initial) { // another constructor 
    balance = initial; 
  }
  public void deposit(double amount) { // instance method deposit 
    balance = balance + amount; 
  }
  public void withdraw(double amount) { // instance method withdraw 
    balance = balance - amount;    
  }
  public double getBalance() { // instance method getBalance
    return balance; 
  }
} 

Once again to see this in action I need to copy the code in two files, one for the bank account class and the other one for the bank account test class (that has the main method). Then you compile them and run the test class.

Can we summarize now? We sure can.

I have a summary with two short examples. Let's see them.

Objects are entities that can have memory and specific behaviour. Their memory is represented by variables that they have inside and their behaviour is defined by actions that they know how to perform ... that is, the methods that are associated with those objects.

All objects of the same kind, that have the exact same structure, make up a class. In fact, in programming it's always the other way around: one first defines a class,

which describes how that particular class of objects will look and behave (what methods they have,) ... then one creates as many objects (of that kind) as needed

... and lets them loose, ... thus running the program.

To better clarify instance variables and instance methods let's look at two examples. Each one will resemble a short play (as in a stage representation of an action or a story).

Our dramatic compositions will be simple, since we will abstract away all the unwanted details. The titles of the plays will be:
  • Sports, and
  • Babies.

Better than "You are old Father William" already. OK, let's look at the first one.

A Hoosier basketball fan's simple to describe: ... she cheers, by shouting 'Go Hoosiers!' when she feels like cheering for the former team of Bob Knight, and that's the end of it.

Write a short program (a play) that presents three Hoosier fans cheering for the IU Hoosiers, .. each fan cheering once, and in no particular order.

Here's how the program should behave: The output of the program is in blue.
tucotuco.cs.indiana.edu% javac Sports.java
tucotuco.cs.indiana.edu% java Sports
Go Hoosiers!
Go Hoosiers!
Go Hoosiers! 
tucotuco.cs.indiana.edu%

At a basketball game the noise is so loud that you don't know who is cheering and when. The crowd is anonymous, more or less. Here's the object oriented implementation of this play:
public class Sports {
  public static void main(String[] args) {
    Hoosier a = new Hoosier(); 
    Hoosier b = new Hoosier(); 
    Hoosier c = new Hoosier(); 
    a.cheer();
    b.cheer(); 
    c.cheer(); 
  } 
} 
 
class Hoosier {
  void cheer() {
    System.out.println("Go Hoosiers!"); 
  } 
}

Just a quick question: for all practical purposes cheering here essentially means printing, right? Printing, or displaying a big printed note,

... which reads (in this case): " Go Hoosiers! ".

So we see that a Hoosier is an object that knows only one thing: to cheer, ... and in only one way.

The objects' behaviour is defined by their methods, and since each object is ... an instance of a class the methods themselves are called instance methods.

OK. Here's the second play, Babies. We won't have much time for that.

Here's the play:
tucotuco.cs.indiana.edu% javac Babies.java
tucotuco.cs.indiana.edu% java Babies
Alice: Hello, my name is Alice
Susan: Hello, my name is Susan
Jimmy: Hello, my name is Jimmy
tucotuco.cs.indiana.edu% 
Looks good to me.

Here's the screenplay and the cast.
public class Babies {
  public static void main(String[] args) {
    Baby a = new Baby("Alice"); 
    Baby b = new Baby("Susan"); 
    Baby c = new Baby("Jimmy"); 
    
    a.talk(); 
    b.talk(); 
    c.talk(); 
   
  } 
} 
 
class Baby {
  String name;                // instance variable 
 
  Baby(String givenName) {    // constructor 
    name = givenName; 
  } 
 
  void talk() {               // instance method 
    System.out.println(name + ": Hello, my name is " + name); 
  } 
}

Oh, but I think I understand instance variables now. Oh, but I am sure you do.


Last updated: Jun 16, 2002 by Adrian German for A201