Session 3 |
Constructor
The instantiation shown in the last example is not efficient. Though, we did not have to make up numerous unique variable names due to dot notation (e.g. liza_name, liza_breed, liza_age, marfa_name, etc.), the number of lines has not been reduced :) Furthermore, such instantiation does not avoid situations when one or more fields of an instance are not defined by chance.
The situation can be improved creating objects in the client class using a constructor that initializes the instance fields:
Dog liza = new Dog("Liza", "labrador", 3, "small", "brown"); Dog marfa = new Dog("Marfa", "beagle", 5, "small", "yellow-white-black");
Variables liza and marfa are ordinary variables that refer to the objects, but their data type is Dog (not String or anything else). Furthermore, the right hand side of the declaration looks a bit like a method call that takes in arguments. This is because the keyword new calls a special method - a constructor.
A constructor is a special type of method that is invoked by operator new
. Constructors create and initialize instances of the object class and typically set the initial values for all the instance fields.
Let us explain the term of constructor in detail.
If we call a special method in the client class, the method should be defined somewhere. The constructor is always defined in the object class after the instance fields. A general syntax for a constructor header:
public ClassName(list_of_parameters) {
Unlike typical methods, in the constructor header:
- the name of the method is the class name (e.g. Dog);
- there is no return type because a constructor always returns an object of its own class.
The constructor is called when a new instance of an object is being created. This means the object description must be set up. If we want the user to be able to specify the initial values of the object's instance fields, the constructor must have parameters that match the instance fields:
// constructor for class ''Dog'': public Dog(String dogName, int dogAge, String dogColor) { name = dogName; breed = "labrador"; age = dogAge; size = "small"; color = dogColor; }
Notice:
- This constructor accepts values for three fields from the client; the other fields are set to defaults inside the constructor.
- If we set the values to instance fields inside the constructor, we do not need to set their values at their declaration (the approach of splitting declaration and initialization is preferred).
In the last example, we used different names for the parameters (e.g. dogName) than the instance fields (e.g. name), but because the parameters and the instance fields store the same type of data, it is preferable to write:
public Dog(String name, int age, String color) { this.name = name; breed = "labrador"; this.age = age; size = "small"; this.color = color; }
What is the keyword this
placed in front of the object fields? Java can distinguish the instance fields from the method parameters by using the keyword this
.
this
, object variable and parameter will have identical names - this will NOT set the values to the fields! In fact, the method parameters will uselessly set themselves to their own values. Oops!
Default constructors
Frankly speaking, we do not have to provide a constructor for an object at all. If there are no constructors in the object class, Java provides a default constructor known as the zero argument constructor.
Remind the example from the last chapter. We managed to create an instance without any implicit constructors - simply using statement Dog liza = new Dog();
.
In such case, the default constructor looks like this:
public Dog() { }
When the client class creates a new object, it cannot pass in any arguments. This means that the fields will initially store their default values (like null for Strings or other objects, or 0 for integers, or 0.0 for doubles):
Dog liza = new Dog();
Can we create our own zero argument constructor? Yes, sure.
public Dog() { this.name = "No name"; this.breed = "Unknown"; this.age = 0; this.size = "Unknown"; this.color = "Unknown"; }
Overloading constructors
In fact, an object class can have as many constructors as we like. This allows the users to decide what amount of data they want to specify when creating an object, and what amount they want to rely on default values.
Just like method overloading, constructors also can be overloaded using different signatures (the number of formal parameters and their data type). We recommend to create a constructor that initializes all fields inside the constructor at first:
public class Dog{ // Instance fields String name; String breed; int age; String size; String color; // Constructor public Dog (String name, String breed, int age, String size, String color) { this.name = name; this.breed = breed; this.age = age; this.size = size; this.color = color; } }
In this example, we have moved all the field declarations within the constructor, giving the user a complete control over the initial state of the object. Now that this constructor exists we can add other constructors that include default values (so that the user does not have to set everything) or call the most specific constructor from the less specific constructors to reduce redundancy. The later means that we call one constructor from the other with the use of keyword this
in the place a method name would normally be:
public class Dog{ // Instance fields String name; String breed; int age; String size; String color; // Constructor public Dog (String name, String breed, int age, String size, String color) { this.name = name; this.breed = breed; this.age = age; this.size = size; this.color = color; } // Default constructor public Dog() { this("No name","Unknown",0,"Unknown","Unknown"); } }
Which one of the constructor will be used for instance instantiation (create an instance) depends on the number of arguments and their data types:
Dog liza = new Dog(); // the default constructor without parameters is used Dog liza = new Dog("Liza","labrador",3,"small","brown"); // the second constructor is used
Last but not least, we can also create a constructor in a fast way using IntelliJ: in the Code menu choose Generate.
The summary of this page can be seen in the video:
Session 3 |