Zo72
Zo72

Reputation: 15305

super(new Something(...)) is this construct wrong?

I am looking at some java code where the constructor of a class looks like this:

public class X extends ... {
    X(String s) {
       super(new Y(s)); 
    }
}

is that always wrong ? in other words is it creating an object in the constructor to pass it to 'super' always wrong ? if so why ?

EDIT: Why do I think it might be wrong ?

when creating a class X the first thing the jvm does is to call super on its super class. (that's done even if 'super()' is implied) you can only do a limited amount of operations such as super(new Y(s)); maybe a call to super with the ternary operator super( s != null ? new Y(s) : new Y() ) but you would not be able to put any more logic because super must be called first !!! That's why I think it's wrong

Upvotes: 2

Views: 807

Answers (5)

T.J. Crowder
T.J. Crowder

Reputation: 1074335

No, it's not always wrong. It's perfectly valid for a subclass to lock in something that the superclass allows you to specify in the constructor.


Re your edit:

...but you would not be able to put more logic because calling super...

That's true, and it's a limitation (an intentional one, I suspect) of the Java programming language, but that doesn't make it always wrong to create an object to pass to super.

And you can get around that limitation if you want, by defining a static function that returns what you need to pass to super and calling it:

super(makeTheThingYouNeed());

At that point, I would definitely double-check that this was really my best course of action before using it. But just creating an object specifically to pass it into super? Not a problem at all.

Upvotes: 3

Fritz
Fritz

Reputation: 10045

It's not Always wrong, but as usual there should be a measure to prevent abuses.

In this case it seems as if the new Y object was a wrapper of the s String or, it was some kind of object required by the superclass of X. You're just providing the initialization values of the superclass, and adapting them when needed.

The Y object can be created in X's constructor or provided as a parameter directly (with X's constructor receiving an Y instead of a String). For example, the creation of Y is ok if it is a class that you don't have access to from the object that creates X.

As you can see, it's all a matter of the current context you're coding in. That very context determines how wrong can a decision turn out to be.

Upvotes: 0

cwallenpoole
cwallenpoole

Reputation: 82028

It is not "always" wrong. It is not even "mostly" wrong or faux pas. For that matter it is fairly common for child classes to pass information to super that way. BUT one does wonder what the other circumstances might be and most of these have little to do with the practice itself.

Is this a way to get around a more extensive initialization of the class? Then maybe it is a bad idea. Does it make it harder to read/debug the code? Then maybe it should be left out.

I also wonder who told you that it was always wrong and why they said that. Was it a fellow developer? A fellow student? An instructor? Categorically saying that "initialization inside of a constructor is wrong" is not something which I have ever seen, but it is something I can imagine a thinks-he-knows-but-doesn't student or professor saying.

Upvotes: 0

Ted Hopp
Ted Hopp

Reputation: 234795

It's not wrong in any language sense. However, perhaps it "smells" (as you put it in a comment) because it seems inconsistent to have a subclass relationship between X and its superclass if the constructors take completely different types of arguments.

This is a subjective matter that has more to do with OO design philosophy rather than with coding practice. As code, it's perfectly reasonable for a subclass to restrict the types of data with which an object can be created. In fact, it's quite common to do this.

Upvotes: 0

Boris the Spider
Boris the Spider

Reputation: 61148

No, it's not always wrong, for example

public class A {
  public A(final BigDecimal value) {}
}

public class B extends A {
  public B(final String value) {super(new BigDecimal(value));}
}

There could be many reasons for doing this, transformation of variables (as above) or maybe the superclass takes an instance of some protected class that only B can instantiate.

Few things are always wrong but many things are sometimes wrong...

Upvotes: 0

Related Questions