Multiple constructors in a class

I am trying to write a class that needs multiple constructors, and I would like some advice about whether one constructor can build off of another one.

I’m really just looking for help understanding what’s possible when using more than one constructor in a class where two or more ways of initializing a class have some variables in common, but need to call different class methods for initialization.

I’ve started to find myself writing a lot of the same code in different constructors of the same class and it’s getting messy.

This is a basic idea of what I am working with right now.

class Class {
  int nObjects, nGaps, objWidth, margins;
  float space, gapSize;
  PVector[] xyCenters;

  Class(int nObjects_, int objWidth_, int margins_) {
    nObjects = nObjects_;
    objWidth = objWidth_;
    xyCenters = new PVector[nObjects];
    nGaps = nObjects - 1;

    margins = margins_;
    gapSize = calculateGaps();
    space = space1();
    xyCenters = method1();
  }

  Class(int nObjects_, int objWidth_) {
    nObjects = nObjects_;
    objWidth = objWidth_;
    xyCenters = new PVector[nObjects];
    nGaps = nObjects - 1;

    gapSize = 5;
    space = space2();
    xyCenters = method2();
  }

  float space1() {}
  float space2() {}
  float calculateGaps() {}
  PVector[] method1() {}
  PVector[] method2() {}
}
1 Like

Yes, you can have just one main constructor and call it from the others using this

eg. Your second constructor could be something like

Class(int nObjects_, int objWidth_) {
  this(nObjects_, objWidth_, 0);
}

Having underscores at the end of variable names is a bit odd in Java.

2 Likes

You can also identify which statements within the constructors are common among them, and transfer those statements to a separate method: :grinning:

class MyClass {
  int nObjects, nGaps, objWidth, margins;
  float space, gapSize = 5;
  PVector[] xyCenters;

  MyClass(int nObjects_, int objWidth_, int margins_) {
    commomInit(nObjects_, objWidth_);

    margins = margins_;
    gapSize = calculateGaps();

    space = space1();
    xyCenters = method1();
  }

  MyClass(int nObjects_, int objWidth_) {
    commomInit(nObjects_, objWidth_);

    space = space2();
    xyCenters = method2();
  }

  void commomInit(int nObjects_, int objWidth_) {
    xyCenters = new PVector[nObjects = nObjects_];
    objWidth = objWidth_;
    nGaps = nObjects - 1;
  }

  float space1() {
    return 0;
  }
  float space2() {
    return 0;
  }
  float calculateGaps() {
    return 0;
  }
  PVector[] method1() {
    return xyCenters;
  }
  PVector[] method2() {
    return xyCenters;
  }
}
2 Likes

I’ve been working my way through Daniel Shiffman’s books, that’s the way it looks in a lot of the examples. How is it usually done? I thought the “temporary” variable in the constructor has to be passed this way with a different name than the class variable.

That’s one way, just not normally by using an underscore. The more common way is to use the same name and this to refer to the field. Eg.

this.nObjects = nObjects;
1 Like

I prefer anything else than using this where it’s completely avoidable. :money_mouth_face:

Well, of course, I wouldn’t expect you to follow the conventions that most other coders use! :roll_eyes:

1 Like

Great. The underscore has caused me nothing but sorrow ever since it started appearing commonly in file names to separate dates and whatnot. It looks nice in a list of files, but double clicking a “word” in a string separated with the underscore always also selected the underscore with it, and so, the whole date.

I’ve been trying to tell myself, you know, maybe the underscore is not so bad. But I still believe it’s nothing more than a leftover from people who were obsessed with the need to play hangman.

1 Like

Between this.foo = foo or foo = foo_ the key thing in code style is convention and, even more importantly, consistency. If you are in a company that has a style, follow it. If you have a personal preference and are generating a lot of code, stick with one. If you don’t care, then you could follow the lead of a big library you are using – for example, check out how toxiclibs or Processing itself does it.

I believe that over a long period of time one of the things that guided more communities towards the this.foo = foo pattern was the way it was used for built-in code generation in IDEs such as Eclipse and Netbeans. For some related discussions, see:

Of course, this is all language/community dependent. Java uses underscores rarely, and has widely followed conventions for a few cases like CONSTANT_NAMES. Python uses underscores in a really wide variety of ways, in technical features of the language, in aspects of the core library, and in naming conventions. https://hackernoon.com/understanding-the-underscore-of-python-309d1a029edc

2 Likes