Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reusing code in overloaded constructors

My BigBlock class needs a few overloaded constructors. All of them need to initialize the same few fields in the same way.

What is the proper way to do this? Is it to make a function, e.g. Initialize in the example below, that does these things, and have all constructors call that function?

public class BigBlock {
    private Thing parentThing;
    Units lengthUnit;
    LabCoordinateSystem labCoordinateSystem;

    private void Initialize(){
        lengthUnit = parentThing.getPreferredUnits(0);
        labCoordinateSystem = parentThing.getCoordinateSystem();
    }

    BigBlock(Thing myThing){
        parentThing= myThing;
        Initialize();
    }

    BigBlock(Thing myThing, double x, double y, double z){
        parentThing= myThing;
        Initialize();
        // more code involving x, y, z
    }

    // a few more constructors

}
like image 656
Jean-François Corbett Avatar asked Sep 21 '11 10:09

Jean-François Corbett


People also ask

How can constructors be reused?

Introduction. The following code shows how to reuse a constructor. The first constructor initializes the name and the price with default values. The second constructor lets you initialize name and price with the value supplied by the caller.

Can constructor call another overloaded constructor?

We can call an overloaded constructor from another constructor using this keyword but the constructor must be belong to the same class, because this keyword is pointing the members of same class in which this is used. This type of calling the overloaded constructor also termed as Constructor Chaining.

Can we override overload constructor?

Constructor looks like method but it is not. It does not have a return type and its name is same as the class name. But, a constructor cannot be overridden. If you try to write a super class's constructor in the sub class compiler treats it as a method and expects a return type and generates a compile time error.

Is it possible to overload constructors?

Constructors can be overloaded in a similar way as function overloading. Overloaded constructors have the same name (name of the class) but the different number of arguments. Depending upon the number and type of arguments passed, the corresponding constructor is called.


2 Answers

Typically it's best to make all constructors chain to a single one which contains the most information, e.g.

BigBlock(Thing myThing) {
    this(myThing, 0, 0, 0); // Assuming 0 is the default value for x, y and z
}

It becomes slightly weirder if there are different ways to call the constructor which don't effectively represent subsets of the same information - but at that point I'd say there's a design smell anyway.

Note that by the time you've got all the real logic in a single constructor, you don't need your Initialize method (which should be initialize to follow Java naming conventions, btw) at all - which may also you can make fields final which previously you couldn't have done.

like image 101
Jon Skeet Avatar answered Sep 20 '22 18:09

Jon Skeet


Just reuse your current constructor. Let every other constructor call the one that initialises all required values.

BigBlock(Thing myThing){
    parentThing = myThing;
    lengthUnit = parentThing.getPreferredUnits(0);
    labCoordinateSystem = parentThing.getCoordinateSystem();

}

BigBlock(Thing myThing, double x, double y, double z){
    this(myThing);
    // more code involving x, y, z
}

If x,y and z need to be part of the initalization, BigBlock(Thing myThing) should call BigBlock(Thing myThing, double x, double y, double z) with default values.

like image 23
kapex Avatar answered Sep 18 '22 18:09

kapex