Showing posts with label CONSTRUCTOR. Show all posts
Showing posts with label CONSTRUCTOR. Show all posts

Friday, 14 September 2012

Multiple Constructor Methods

A special type of method that creates an instance of a method is called a Constructor Method. When an object has member variables that are objects, we need to define a constructor method to set up those variables. We'll show how to do that here. If you want a more basic introduction to constructor methods, you may want to take a look at my prior article.

As an example, we're going to create a simple class of object for use with my simple video game kernel in a new version I'll be introducing in an article in the near future. The class definition consists mostly of constructor methods, since the class itself is presently not much more than a Rectangle with an added field.

import java.awt.*;

// A Simple class for use in the simple video game examples.
// Mark Graybill, Aug. 2010

public class Brick extends Rectangle{
 Color brickColor;

 public Brick(int newX, int newY, int newWidth, int newHeight){
  super(newX, newY, newWidth, newHeight);
  brickColor = new Color(0, 128, 255);
 }

 public Brick(int newX, int newY){
  this(newX, newY, 10, 10);
 }

 public Brick(){
  this(0,0,10,10);
 }

 public void setColor(Color newColor){ brickColor=newColor; }
 public Color getColor(){ return brickColor; }

} // End Brick

In this class, we have three forms of constructor, each with a different set of parameters. The one that takes the most parameters is the "base" version. It starts with a call to super(). This calls the constructor for Brick's superclass, or parent class, Rectangle. A look at the documentation for Rectangle shows that it has a constructor that takes four integer arguments, as we use here in super().

When we use super(), it must be the first thing we do within our constructor method. If we don't use super(), Java will do it automatically as the first thing in a constructor, calling it with no parameters. Since we want to set values for our inherited fields of x, y, width, and height it's better to call super() with those parameters. Otherwise, we could just as well have done something like this:

  public Brick(int newX, int newY, int newWidth, int newHeight){
  x=newX;
  y=newY;
  width=newWidth;
  height=newHeight;
  brickColor = new Color(0, 128, 255);
 }

This would have the same effect, and Java would insert an invisible call to super() in front of x=newX;.

The other constructors use the first method. To do this, they use another special method that's like super(). It's called this(), and it calls another constructor for this class. We can't do a call to Brick(), if we try, the compiler will see it as an undefined symbol:
>javac Brick.java 
Brick.java:11: cannot find symbol
symbol  : method Brick(int,int,int,int)
location: class Brick
    Brick(0,0,10,10);
    ^
1 error

So we use this() instead.

Like super(), the this() method must be the first thing called in the constructor method's body. Since don't call super()--it's in the base constructor--so there's no conflict about which goes first. If you use this(), you don't use super().

By using this() with the other constructor methods, we can keep all our key code code for the constructor in one place. If we had each constructor setting member values and constants without calling the base constructor method, then we'd end up with repeated code--a prime opportunity for bugs to enter our code if we update the code in one place, but not another. We don't want repeated code! Multiple independent constructors are used in the Java Tutorials, but I expect they're used to keep the lesson simple, not because they are a good coding practice!

You can find out more about this() and super() in the Java Language Specification, under Explicit Constructor Invocations.

You can probably see that I should really have my base constructor allow a Color to be passed to it, too. Try adding this yourself as an exercise to try out your understanding of constructor methods, then see what javac thinks of your work.

Constructor Methods

A constructor method is a method that creates an object. To create the object, it uses the class as a sort of blueprint for what member variables the object has, what instance methods, and so on.

The name of a constructor method is the same as the name of the class. For example, if we have a class named Dragon its constructor will be named Dragon as well:

public class Dragon{

  public Dragon(){
    super();
  }
}

There are a couple of things to notice here. One is that, unlike a regular method, the first character is upper-case, just like the class name. The constructor name must exactly match the class name. While it is only a convention that classes (and therefore, their constructor methods) start with a capital letter, it is an iron-clad requirement that the constructor name match the class name.

The other thing you'll want to notice is that there's no type given in the method declaration. A normal method (called an instance method, if we want to get formal) has a type provided in its declaration, just as a variable has a type in its declaration:

public void dragon(){ }    // Instance Method.
public int dragonCount;    // Instance Variable.
public class Dragon{ }    // Class.
public Dragon(){ }    // Constructor.

In the constructor's declaration, there's a scope called out (public) but no type. This is because, as a constructor for the object, it will be returning an object of the type it is a constructor for. OK, that sounds worse than it is. Let's try again...

A Dragon constructor returns a Dragon object. A String constructor returns a String object. That's what it constructs, so that's what it returns. Declaring a type would be redundant:
public Dragon Dragon(){ }    // This is NOT correct code, just an example of silliness!

A Subtle Error
If you accidentally have a typo in your program that results in your class and constructor having different names, the compiler will complain that you've got a method without a type declaration. You'll look at the code and say "Hey! That's a constructor. It doesn't need a type declaration! What is my compiler smoking?"

public class Dragon{

 public Dragin(){
   super();
 }
}

Dragon.java:3: invalid method declaration; return type required
 public Dragin(){
        ^
1 error

What's happening here is that the compiler sees that the name of the method is different from the name of the class. Aha, it says, this isn't a constructor since it doesn't have the same name as the class. So it must be an instance method. Hey, instance methods need a type! There's no type! Then it prints the error message.

Note that spelling errors include capitalization. So having a class named Dragon with a constructor called dragon() would cause the same error.

For more about constructor methods, see Multiple Constructor Methods