Java Programming   Java Programming
 |Sofia Home | Content Gallery |
Home
Syllabus
Schedule
Lessons
Assignments
Resources

Lesson 9.2 Default Constructor

Constructors

This lesson will teach you how to create default constructors for the classes you create. Then, you'll modify the LTextField1 class, adding your new default constructor, so you no longer need to call the init() method when you use your objects. This new version, LTextField2, will make objects that act just like the built-in components.

Constructors are like methods in some ways, and unlike methods in others. Probably the closest comparison is to a static or factory method where you send a message to a class instead of sending a message to an object. 

Illustration shows a Keypad Factory turning out Keypad objects.

Even that comparison fails in some points, so it's best to mentally put constructors in their own category.

Constructors are defined, like methods, inside a class definition. When you use the new operator to construct an object of your class, the new operator contacts your class, and your class uses the constructor you've written to initialize the object it creates. 

Whew! If you think of a class definition as the blueprint for defining objects, then think of the constructor as the factory for creating objects.

Back to Top

Constructor Syntax

Inside your class a constructor looks exactly like a method definition with two constraints:
  • A constructor will always have the same name as the class that contains it. There are no exceptions.
  • The constructor will have no return type, not even void. Writing a constructor definition using a return type does not create a syntax or runtime error. It just doesn't work. If it has a return type, then it is a method, not a constructor, even if it has the same name as the class.

This illustration [click image to enlarge] shows the basic syntax used for defining a default constructor.

The syntax of the default constructor.

Constructors almost always start with the keyword public, which is always followed by the name of the class. The class name is then followed by a pair of empty parentheses. 
Inside the body of the constructor, which is delimited by braces, just like the body of a method, you can have any number of statements. The purpose of the statements is to initialize the fields in your newly created object.

Back to Top

The Default Constructor

The default constructor [sometimes called the no-arg constructor] is the constructor that is called when you supply no arguments. It is called the default constructor because its purpose is to initialize each field in the object to a predefined or default value, so the object is in a usable state.

Here are some default constructors you've already met:

Button btn = new Button();
Label  lbl = new Label();
Panel  pnl = new Panel();

As you can see, sometimes a default constructor is pretty useful, and sometimes it isn't. The Panel object pnl is perfectly functional using the default constructor, but the Button object btn and the Label object lbl are pretty useless as is. 

The important thing to see, however, is that, thanks to the default constructor, even Button and Label objects are "well formed"; you won't get a "NullPointerException" message if you try to send lbl the setText() or getText() message. You don't have to do any additional initialization to send messages to each of these objects.

Back to Top

The LTextField2 Class

Let’s create a default constructor for the LTextField class. We'll start by copying LTextField1.java to LTextField2.java and then renaming the class contained in the new file.

 

Why Rename?
Throughout this lesson, I'll make several copies of the LTextFieldX class, renumbering and renaming each one. The only reason for doing this is so that you can see--as well as download and try out--each version of the program as it is developed.

If you want to simply make one LTextField class and modify it as you go, that's fine.

Next, let's "clean up" the basic structure of the class by changing extends Applet to extends Panel. Even though the Applet class is descended from the Panel class, the Applet class adds a lot of extra functionality that's not really appropriate for our LTextField classes.

Here are the steps you need to follow to create a default constructor for LTextField2:

1. Rename the init()method to LTextField2()

2. Remove the return type of void>

3. In the Label constructor, remove the text "Name", but leave the double quotes. For a default constructor, having a Label with no text makes more sense than a Label that says Name.

4. In the TextField constructor, change the default size to 15 from 40, which is a little long to be useful.

You can see the finished LTextField2.java here:

LTextField2.java
import java.awt.*;
import java.applet.*;

public class LTextField2 extends Panel
{
  Label     theLabel;
  TextField theText;

  public LTextField2()
  {
    theLabel = new Label("Name:", 
                     Label.RIGHT);
    theText  = new TextField(15);

    add(theLabel);
    add(theText);
  }
}

Let's also make a new program to test LTextField2 by copying User1.java to User2.java. Here are the changes you'll have to make to User2.java:

1. As with LTextField1, you'll have to change the name of the class from User1 to User2.

2. Change the type of each field to LTextField2, and change the constructor invocation from new LTextField1() to new LTextField2().

3. Remove the init() messages sent to each of the fields inside the User2 init() method.

 

User2.java
import java.awt.*;
import java.applet.*;

public class User2 extends Applet
{
  LTextField2 first  = new LTextField2();
  LTextField2 second = new LTextField2();

  public void init()
  {
    first.init();
    second.init();
    add(first);
    add(second);
  }
}

When you're finished, create User2.html, compile your program and run. As you can see, the program works a little different than it did before. For one thing, the Label is invisible and the TextFields are smaller. 

Running the User2 applet

The biggest change, however, is not visible on the surface; this time, you didn't have to send an init() message to each of your objects. Instead, they worked just like the built-in objects.

But new LTextField1() Worked. Why?
In User1.java, before you even started thinking about constructors, you created an LTextField1 object like this:

  LTextField1 first = new LTextField1();

Since the LTextField1 class didn't have a default constructor, then why did this work at all? 

The truth is, you don't have to write a constructor. If your class does not contain a constructor, then Java will "write" a default constructor for you, as it did for LTextField1.

This automatically written constructor doesn't actually do any initialization, and, if you write any constructors at all, Java will no longer write the default constructor.

Back to Top

Constructive Evaluation

The purpose for writing a default constructor is to put your objects into a "known" state when they are created. But a known state is not the same as an ideal state. For instance, a Label or Button with no text are not very useful.

The same thing is true with the LTextField2 constructor. It has made our objects easier to use: we don't have to send the init() message to each object to complete the initialization, but we still aren't where we'd like to be. We still can't easily create a labeled text field that says "Address:", for instance.

For that, you'll have to wait till the next lesson when you learn to write a variety of overloaded constructors.

Something to Talk About

At the end of the previous section, you were asked to describe two components that you could create using existing components. What default initialization needs to occur in the default constructor for each of your components?

Please continue to the next section of this lesson.

 

Back to Top

 

Content Developed by Stephen Gilbert, Licensed under a Creative Commons License
Published by the Sofia Open Content Initiative
© 2004 Foothill-De Anza Community College District &The William and Flora Hewlett Foundation