One-arg ctor A (x) implicitly calling super () and NOT super (x)

class A{

    A(int x){}
}

class B extends A{

    B(int x){}

    public static void main(String args[]){
         B b = new B(10);
    }
}

      

I understand that this will throw an error (one-arg-constructor for B, implicitly calls super (), whereby a default-arg constructor does not exist for A). I'm curious why the one-argument constructor for B doesn't use super (x) to call the one-argument constructor of class A. On the contrary, inserting me into the essence of explicitly writing a no-arg constructor for A when I don't require one!

+2


source to share


10 replies


You can rewrite your class B like this:

class B extends A{
    B(int x) {
        super(x);
    }
}

      



which will do what you want. This happens implicitly, since there might be many different constructors in (your example doesn't have them, but maybe), and he wouldn't know which one was correct. What if you had one class that occupied length and width, which somehow overrides the class with width and height. You would not want Java to automatically call the superclass constructor simply because the argument types are matched. You will need a compilation error forcing you to explicitly call the superclass constructor with the appropriate / correct arguments.

+11


source


The reason you get an implicit zero-argument constructor call for super is because the compiler knows what you want super to build - it just doesn't make sense otherwise, and the zero-arg constructor is simple, and generally the right choice. Asking the compiler to be smarter than that is unrealistic. You might say, "Hey, there is only one constructor, and it takes the same number of arguments - how difficult is that?" But it is very difficult; the possibilities of what you might need in this case are wide open. So a safe policy: if you want something more than the no-arg constructor, the compiler requires you to call it explicitly.



+4


source


All you have to do is

B(int x){ super(x); }

      

There is no need for a default constructor, but you need to call the one-arg constructor from A.

It looks like the compiler can help you, but Java is so much sometimes.

+2


source


The no-arg constructor always knows what it does, since it doesn't depend on any external data; OTOH is a constructor with some arguments, which the companion cannot be sure what they mean, so it asks you (the human) to confirm which one to use.

Example:

class A{
    A(int numberOfYears){}
}

class B extends A{

    B(int numberOfApples){}

    public static void main(String args[]){
         B b = new B(10);
    }
}

      

I think it's more clear why the compiler doesn't use this super(int)

default constructor .

+1


source


As Zen of Python says: Explicit is better than Implicit

So change B(int x){}

toB(int x) { super(x); }

+1


source


Then you must explicitly call super (x) at the beginning of your function. Basically Java will add a super () call, if it doesn't find a super call of any type - add it and you should be fine.

0


source


Perhaps because the java designers thought it was more likely that the superclass has a default constructor than a constructor with the same signature you want to call. Also, perhaps because the rule "if you don't call super explicitly, it uses the default constructor" is easier than "if you don't call super explicitly, it uses the superclass constructor with the same signature."

0


source


I'm wondering why the one-arg-constructor for B, doesn't use super (x) to call the one-arg-constructor of class A.

If you're asking this as a language design question ...

I think the Java developers thought that the more complex semantics for the implicit super

"call" would be more difficult to understand. For example, what if the type of the parameter of the superclass's constructor is different from the type of the parameter in the subclass? What if there were multiple constructors in a supertype?

I personally don't think it's a duty to include an explicit call super

in every constructor. Indeed, many people think this is good style.

0


source


The reason is that when you define a parameterized constructor in a subclass, you want to OVERRIDE something from the superclass. Therefore, the superclass is not named AUTOMATICALLY. However, you can call super (param) (in case you are just ADD to functionality). But this should be the first call.

However, the DEFAULT constructor named DEFAULT. so it will ALWAYS be called (in the given JLS order) when the object is created.

0


source


As others have pointed out, in the example you give, it wouldn't be a big problem to explicitly call the one-arg constructor.

What worries me more is when I have a superclass A with two subclasses B and C, and B and C both require the same 10 parameter set constructors. It seems to me that the whole point of inheritance is that I would have to put these constructors in and should not write the same code twice or even write 10 pass-thru functions twice.

If I can write a regular function in a class that its subclasses inherit, why can't I write a constructor?

I wonder if this is one of those problems where if I read the code to the compiler I would say, "Ah, I see, if they tried to do this, they would run into this and that problem, and it would just be ugly a mess. " Or maybe they were just brain dead the day they wrote this code. I have never heard of a satisfactory explanation as to why this could not be done to work.

One idea that comes to me: suppose B continues to A. A has a function x () that returns an int. B inherits this function, so B now has a function x () that returns an int. A has a constructor A that actually returns an object of type A. But the constructor for B would have to return an object of type B, not A. So it is not actually inherited, it should be more like "extrapolated" than inherited. So it's not exactly the same.

However, if I say that if I have a class A with a constructor A (int x, int y) and B extends A, then the compiler can automatically generate a constructor B (int x, int y) that calls A ... that it looks like he should be capable. Of course, maybe this is not what I want to do. But then give me a way to override it, for example by explicitly declaring another construct B (int x, int y). In real life, I almost always reproduce all my constructors in subclasses.

0


source







All Articles