Skip to content

The Constructor#

Let's take this Label class (second tab) as an example. It has three attributes and can draw a label with its .show() method.

Label city = new Label();

void setup() {
    size(200, 100);
    city.text = "Darmstadt";
    city.size = 20;
    city.backgroundColor = #7fdfff;
}

void draw() {
    background(255);
    translate(10, 50);
    city.show();
}
class Label {
    float size;
    String text;
    int backgroundColor;

    void show() {
        push();

        // preparations
        translate(0, -(size+10)/2);
        noStroke();
        textSize(size);
        float width = textWidth(text);

        // background
        fill(backgroundColor);
        rect(size, 0, width + 10, size + 10);
        triangle(size, 0, size, size + 10, 0, (size+10)/2);

        // text
        fill(0, 0, 0);
        text(text, size + 5, size * 0.85 + 5);

        pop();
    }
}

Light Cyan Label that reads "Darmstadt"

The Main Code Creates a new object of type Label in a variable called city. We later set the three attributes, and finally draw() will call city.show() to actually draw the results to the screen.

But in between creating our instance in line 1 and setting the .text, .size and .backgroundColor in the setup()-function, this object is "broken". None of the information is available, and if we instead did this:

Anti-Example!
Label city = Label();
city.show();

We would be presented with a NullPointerException error, because we're trying to draw a text we haven't even set, yet! Wouldn't it be cool, if the created object was working right from the start? That is, where the constructor can help you.

Default Constructor#

A constructor is what's running when you create a new instance. In all our previous examples, we were using constructors, we just didn't see them, because we did not write our own constructors. In those cases, Java just creates an empty object.

This is also, why instantiating a new object looks a little bit like a function call. Label city = new Label(); specifically that second part with the parentheses! The constructor is what returns our new object.

Creating Your Own Constructor#

Let's say we always want our label to at least not break anything. We should set default values for .text, .backgroundColor and size and we can do this by providing our own constructor which replaces that default constructor:

class Label {
    float size;
    String text;
    int backgroundColor;

    Label() {
        size = 20.0;
        text = "";
        backgroundColor = #d0d0d0;
    }

    void show() {
        push();

        // preparations
        translate(0, -(size+10)/2);
        noStroke();
        textSize(size);
        float width = textWidth(text);

        // background
        fill(backgroundColor);
        rect(size, 0, width + 10, size + 10);
        triangle(size, 0, size, size + 10, 0, (size+10)/2);

        // text
        fill(0, 0, 0);
        text(text, size + 5, size * 0.85 + 5);

        pop();
    }
}

That newly created thing looks a little bit like a function without a return type. It is also weirdly named with a capital letter and therefore has the exact same name as the class itself. Congratulations, these two things (no return type and same name as the class) are what makes this a constructor!

No Return Type for the Constructor

A constructor will return our newly created object, so for some reason it has to be written with no return type at all. But we're also not calling return anywhere. It just returns the object anyway.

Constructor with Parameters#

Since this looks so much like a function call, let's try adding Parameters!

Label city = new Label("Darmstadt");

void setup() {
    size(200, 100);
}

void draw() {
    background(255);
    translate(10, 50);
    city.show();
}
class Label {
    float size;
    String text;
    int backgroundColor;

    Label(String labelText) {
        size = 20.0;
        text = labelText;
        backgroundColor = #d0d0d0;
    }

    void show() {
        push();

        // preparations
        translate(0, -(size+10)/2);
        noStroke();
        textSize(size);
        float width = textWidth(text);

        // background
        fill(backgroundColor);
        rect(size, 0, width + 10, size + 10);
        triangle(size, 0, size, size + 10, 0, (size+10)/2);

        // text
        fill(0, 0, 0);
        text(text, size + 5, size * 0.85 + 5);

        pop();
    }
}

With this change to our constructor, we can now set the text in the exact moment that this object gets created. In fact we have to set a text (even if it's an empty text). Because the constructor demands a parameter.

Of course we can still modify the attributes later-on.

Constructors are Powerful

Using a constructor is often a good idea. You get to set up default values and other internal things. You can make sure your object has everything correctly set up before anyone gets to see it.

lots of labels in different colors