Constructors

Started by
3 comments, last by szigeti_roland 12 years, 3 months ago
I've never really understood why constructors are necessary. Could someone explain to me why they are needed and what EXACTLY do they do?

Thanks,

Morley
Morley

Aspiring programmer, modeler and game designer.
Advertisement
Would you otherwise create an invalid object and then manually initialize it? Why allow this temporary invalid state? When you receive an object somewhere, you would have to ensure that it has been initialized. Ideally, an object just should not be able to be in an invalid state.

More theoretically, the constructor is supposed to make sure new objects obey the class invariant. Of all possible states, only a handful could be valid. For example, if you have a Linked List class, which explicitly keeps track of its length for efficiency, you want this length field to accurately reflect the length of the list object. A constructor makes sure this is the case for newly created objects. After this, every method can assume the invariant is satisfied (i.e. it can assume the length-field is correct), do its thing, and make sure at the end it leaves the object in an invariant-satisfying state.
Very simply: Constructors are setup routines that configure an instance of a class into some valid state.

Take a daft example of a class that models a sentence of words. We'll say that our application requires that a sentence be made up of text (duh), so if you don't have any text then you don't have a sentence.

In a world where constructors don't exist we might write the class thusly:

[source lang="java"]class Sentence {
private String text;

public void setText(String newText) {
// ensure the text has some actual content to it, don't permit the change if it's null or if it's an empty string ""
if ( newText == null || newText.isEmpty() ) { fail(); }
text = newText;
}

public String getText() { return text; }

}[/source]

You can see that the setter method checks and enforces the class invariant so that we're doing our best to ensure that a sentence is always made up of some actual text. You are not allowed to have a sentence without any text so if you try to call setText("") or setText(null) then it will fail (I haven't defined the fail() function, in a real application you would want to throw an exception).

So at first glance this looks okay, unfortunately we're in a world without constructors so the following usage is possible:
Sentence mySentence = new Sentence();
String theWordsInMySentence = mySentence.getText(); // uh oh getText has not returned any words!


In that snippet we've constructed a new Sentence object but unfortunately if we call getText() we find it returning invalid results. Given that a sentence must, at all times, consist of some amount of text then we appear to have blundered in our design of this class because we've permitted the possibility of constructing invalid sentences.

Adding a constructor will fix the problem:

[source lang="java"]class Sentence {
private String text;

public Sentence(String textToInitialiseTheSentence) {
setText( textToInitialiseTheSentence );
}

public void setText(String newText) {
// ensure the text has some actual content to it, don't permit the change if it's null or if it's an empty string ""
if ( newText == null || newText.isEmpty() ) { fail(); }
text = newText;
}

public String getText() { return text; }

}[/source]

The reason why the problem is now fixed is that it is impossible for a user of this class to construct an invalid Sentence, they can only do it through the available constructors and we've only defined the one. So Sentence construction now looks like this:

Sentence mySentence = new Sentence("Hello this is my sentence.");
String theWordsInMySentence = mySentence.getText(); // yay, no longer returning invalid results


Choosing not to use that constructor would fail at compile-time. Choosing to pass in an empty string or a null string would fail at run-time in the imaginary fail() function and the Sentence object would not be created. We've finally secured our class invariant and Sentence objects can never become invalid at any point during their lifetime smile.png
dmatter is correct in that they are used to initialize an object.

However, I'd say they aren't always "required".
This example their exists not declared constructor.


public class Test {
static final int a = 1;
static final int b = 2;
}


You'll actually find a lot of object like this in code prior to the introduction of Enums in Java since that's just what people did to create their enumerated constants.

Technically, when you don't declare a constructor it still gets the default constructor. The default constructor is needed because every object and variable has to have a point in time where it is initialized or where memory is allocated for the object or variable to exits. For objects in java it's when you use new in conjunction with the constructor.

Test t = new Test();
Constructors set private members to null for example.

This topic is closed to new replies.

Advertisement