15

I was looking at other questions on SO, but I didn't really see an explanation for my question. I read that calling a constructor from another constructor (using the this keyword) was valid, but I didn't understand why it was valid.

Previously, I thought that only one constructor could act per object. Constructor chaining seems to break this logic, in that while calling one constructor, it runs another in conjunction to the original, targeted constructor. Why does constructor chaining work?

5
  • 9
    Why it should be invalid? Commented Jun 23, 2017 at 11:54
  • 5
    It was in C++ until C++11 (i.e. about 30 years). To me that gives this question validity.
    – Bathsheba
    Commented Jun 23, 2017 at 11:55
  • 4
    To clarify @Bathsheba's comment: constructor chaining was invalid in C++ until C++11. (At first glance, I mistakenly read it as if it was [supported] in C++ until C++11)
    – tjalling
    Commented Jun 23, 2017 at 17:05
  • Top answers currently only tell why delegating ctors are useful, not why they're not invalid.
    – geometrian
    Commented Jun 23, 2017 at 19:01
  • @LordFarquaad Yes. My point is that the top answers don't mention anything of the sort at all.
    – geometrian
    Commented Jun 24, 2017 at 22:25

6 Answers 6

14

We chain (call) one constructor from other within the same class so that we can avoid code duplication. Without chaining every constructor, we end up repeating business details and that leads to code duplication and hard to maintain the code as well.

Imagine you are creating a Bus.

public class Bus {  
      int noOfSeats;  
      String busColor;  

      public Bus() {  
           this(40); //// Using another constructor and proceeding with default values..   
      }  
      public Bus(int seats) {   
           this(seats,"red"); // Using another constructor and proceeding..   
      }  
      public Bus(int seats, String color) {  
           this.noOfSeats = seats; 
           this.busColor = color;  
      }  
 } 

And the person using this class can use only constructor at a time, where as you are using chaining internally. Imagine that you have a method which initializes things with default values and calling it in the constructor. There's nothing wrong in that, right?

Just to clarify, the person who is creating the object is calling only one constructor. The invoked constructor calls others which is internal to that class.

7
  • 3
    So just to clarify, the programmer's use of internal constructor chaining is allowed, but the user of the class can only call one explicit constructor per object, right? Commented Jun 23, 2017 at 12:40
  • That's not the default constructor.
    – OrangeDog
    Commented Jun 23, 2017 at 15:16
  • 3
    Also, this is a very odd example. You're allowed to have a bus with no seats and no color? Usually you chain them the other way around.
    – OrangeDog
    Commented Jun 23, 2017 at 15:17
  • @OrangeDog Corrected. default, I mean the no-org constructor. And also, refactored my example completely. Hope this clears up. Commented Jun 23, 2017 at 15:39
  • 1
    @KaienYang You're allowed to chain constructors as a language feature to reduce duplication for the benefit of the class (writer) - a class user is still limited to calling a single constructor.
    – Gwyn Evans
    Commented Jun 23, 2017 at 20:10
9

Delegated constructors reduce the amount of duplicate code, since you can exploit the functionality set up in one constructor by calling it from another one.

Until this feature was designed into languages, we had to rely on "initialisation"-type functions that were called from constructors. That was a pain for two reasons (i) you could never guarantee that the functions were only called from constructors, and (ii) calling class methods from constructors is always a design "smell".

1
  • 1
    Another downside that is a corollary of (i): fields initialized in initialization methods cannot be declared as final.
    – dj18
    Commented Jun 23, 2017 at 16:11
3

It allows to clarify the logic and reduce the code.

Is nesting constructors (or factory methods) good, or should each do all init work

It's reasonable to chain constructors together, the version with fewer parameters calls the version with more parameters. It makes very clear what's happening, and all the real "logic" (beyond the default values) is in a single place. For example:

public class Foo {

    private static final int DEFAULT_X =10;
    private static final int DEFAULT_Y =20;

    private int x;
    private int y;
    private int precomputedValue;

    public Foo(int x, int y) {
        this.x = x;
        this.y = y;
        precomputedValue = x * y;
    }

    public Foo(int x) {
        this(x, DEFAULT_Y);
    }

    public Foo() {
        this(DEFAULT_X, DEFAULT_Y)
    }
}
1

Not a Java dev here, but in Python this is also allowed and pretty much normal.

Whenever you inherit a class, you might want to call the parent class's constructor prior adding your own stuff-and-recipes.

This allows you to benefit the parent class's construction features. Whenever you do not know exactly what the parent class does you most of the time always call it first in order to avoid the parent's class features and methods being broken.

2
  • Btw, the fact that the OP is using this in Java, means that they are not asking about calling a parent class constructor. In Java, you need to use super to reach a parent class constructor.
    – Bathsheba
    Commented Jun 23, 2017 at 11:52
  • Yup, the same in Python ( _ _ super() _ _ ), but I did not know for Java. There is no private method per se in Python, so you can call even the 'private' methods. Constructor methods might prove useful if they take parameters, so I guess it makes sense that those are exposed in Java. (In Python constructors do not return values... Don't know for Java)
    – Fabien
    Commented Jun 23, 2017 at 11:55
1

The fact that the confusion originates from every instance should call one ctor is absolutely right. The constructor chained another is used to avoid code duplication and simplicity because copying same code is really overhead. Sometimes maybe we need two constructors, first one just takes two parameters the other one takes three parameters. But, three parameters-ctor uses same variables of two parameters-ctor. Do you prefer copy-paste same assignmets or merely call the other ctor by this?

0

As a supplement to the other answers, I would like to share another use for calling a constructor from a constructor that I use often.

Another strategy of constructor chaining that I find useful is providing default implementations / auto-injection for Interfaces.

public class Foo {

    private readonly ILogger _logger;

    //Default implementation for most cases
    public Foo() : this(new DefaultLoggerImplementation()) {}

    //DI Constructor that allows for different implementations of ILogger 
   //(Or Mocks in testing)
    public Foo(ILogger logger)
    {
        _logger = logger;
    }

    public void Log(string message)
    {
        _logger.log(message);
    } 
}

This way if you have a default implementation for an interface it is auto injected via new Foo()

If you have a case with different ILogger behavior it is easily injectable, this also promotes the ability to Mock the interface in your unit testing framework.

Not the answer you're looking for? Browse other questions tagged or ask your own question.