0

This question is more about good programming practises and design decisions, but it is centred around the switch in the constructor.

Idea is to handle default behaviour in variety of ways. Default constructor (Const()) handles the simplest or most common case, and parametrized constructor (Const(int type)) uses switch to enumerate other specific cases.

To save some code I could define default constructor in, say case: 0, then I could refer to it from the basic constructor like so:Const() { this(0); } (and I could not do it otherwise (i.e. refer to basic constructor from switch case) because compiler demands one and only one reference to another constructor as first statement).

But I would like to also be able to handle incorrect input in the parametrized constructor with sending default: case to case: 0 (maybe in combination with error message like “Invalid case. Using default case (0) instead.”) or vice versa to make it more robust.

I searched and read other questions here (see this and that, for instance), and I could see where it could be done with some sort of twisted switch fall-through scheme, but for the sake of semantics and clarity I would like to keep the default case first, or, on the other hand, is it possible to refer to default statement via the constructor (such as this.Const(default) or the sort)? Can it be done at all, and if so, what are philosophically best approaches to this problem?

Community
  • 1
  • 1
theUg
  • 1,284
  • 2
  • 9
  • 14

2 Answers2

1

How about handling each case in a separate method?

Then you can do:

case 0: handleCase0(); break;
default: complainThatThisShouldntHappen(); handleCase0(); break;

note that when you are using an Enum instead of an integer for the switch, the type safety checks by the compiler should make the default case obsolete.

Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194
  • I surely cannot call a method of an object I had yet to create (which is what I am doing in the `switch`), can I? – theUg Nov 27 '12 at 07:57
  • 1
    @theUg: You can call instance methods from within the constructor, it's quite common practice. So your zero-argument constructor would call a method that does the zero-argument construction, and your parameterized constructor would also call that method, both from case `0` and from `default`. – T.J. Crowder Nov 27 '12 at 07:59
  • Why not? You can do `returnObject = createObject0(args);` for example. – Has QUIT--Anony-Mousse Nov 27 '12 at 09:01
0

While the question still stands for the academic purpose, here is how I dealt with the issue. Before I had constructor that created objects using switch statement based on the type variable (which probably would be better to handle with specific Enum class). Each of my cases loaded the images to associate with an object, which made it very cumbersome. What I did now is much simpler:

// Default constructor for most common uses.
ClassName() {
    this(0);
}

// Parametrized constructor
ClassName(int type) {
    this.type = type;
}

Now images are loaded via the class tasked with GUI (thus separating the duties) one of whose methods returns an array of images indexed according to the type of the object which is then used in the draw method:

public draw (Graphics page, BufferedImage[] backgrounds) {
    // Misc. calculations.
    page.draw(backgrounds[type], getX(), getY(), null);
}

So it makes for much more elegant solution.

theUg
  • 1,284
  • 2
  • 9
  • 14