5

On this piece of code I understand it works with either super(t) in Class A or a no args constructor in class B. Below the code uses the no args constructor in class B. I understand that if you take the no args constructor out of class B the code does not work. I'm new to programming and what I'm trying to understand is what is so special about the no args constructor in class B, Why does it have to be present for the code to work? What is the special condition or rule?

public class Test {

    public static void main(String[] args) {

       B b = new B(5);

    }
}

class A extends B {
    public A(int t)  {

        System.out.println("A's constructor is invoked");
    }
}

class B  {

    public B() {

    }

    public B(int k)   {
    System.out.println("B's constructor is invoked");
    }
}
Nandkumar Tekale
  • 16,024
  • 8
  • 58
  • 85
John W
  • 161
  • 1
  • 1
  • 6
  • `B(int)` say you must give it an `int` value to construct it. If you have a `B()` Java can call this by default as it doesn't need to know which values to give it. – Peter Lawrey Jan 10 '13 at 08:16

7 Answers7

2
class A extends B {

Compiler ensures while compiling this class; if programmer doesn't write this() or super() explicitely, it will add super() as very first line in every constructor provided in class A.

And compiler also ensures to add no-arg constructor to a class if no other constructor in provided by programmer.

Now, lets say you don't provide no-arg constructor in class B and compiler will also no provide cause you have provided constructor with argument. But, in class A it'll add super() as very first line in constructor. i.e. a call to base class no-arg construtor. Thus, it'll lead to compiler error.

So, as you said, either provide no-arg constructor in class B OR write super(<int>) in class A.

Azodious
  • 13,752
  • 1
  • 36
  • 71
  • Good answer, when class A adds super() to the first line, it is looking for the no args constructor in class B. Is any information sent between them behind the scenes? – John W Jan 10 '13 at 06:58
  • No data passed from one class to other. just the constructor is called which creates object of it's super class and hides the reference within this object. thus you can call inherited methods directly as if they are present in same class. – Azodious Jan 10 '13 at 07:19
1

If there is no constructor defined in class B then there will be implicit default constructor, otherwise you need to explicitly define no-arg constructor.

why we need no-arg constructor?

When A is being instantiated through constructor

public A(int t)  {

        System.out.println("A's constructor is invoked");
    }, 

there is implicit super() call to B(), but if you don't define no-arg constructor this can't be completed which is why you are getting error message.

kosa
  • 65,990
  • 13
  • 130
  • 167
1

Java will not add no argument constructor if you define any other constructor.
No argument constructor is default constructor used by Java whenever required.

Ajinkya
  • 22,324
  • 33
  • 110
  • 161
1

The word isnt "Special" it is "Default".

If you choose not to call a superclass constructor in A(int t) then by default the constructor B() is called, because Java cannot decide for you which other constructor can be considered default. Thus if B() doesnt exist and there is a call to it (as in this case), compile fails.

To clarify, the compile fails because of your definition of class A and not because of the line B b = new B(5);, that line is OK.

Karthik T
  • 31,456
  • 5
  • 68
  • 87
  • i thought public B(int k) {System.out.println("B's constructor is invoked"); is a constructor? – John W Jan 10 '13 at 06:27
  • @JohnW yes, but Java does not choose that to be a default constructor, if only because it has no idea what parameter to pass it. – Karthik T Jan 10 '13 at 06:28
1

what is so special about the no args constructor in class B, Why does it have to be present for the code to work? What is the special condition or rule?

--> When you do not provide any constructor in your class. Compiler adds no-arg/default constructor in your class.

If you have constructor with arguments then compiler will not add default constructor, you will have to add if required.

Nandkumar Tekale
  • 16,024
  • 8
  • 58
  • 85
1

All constructors for classes other than Object must start with either a "this" call, invoking another constructor of the same class, or a "super" call, invoking a superclass constructor.

If there is no explicit "this" or "super" call at the start of a non-Object constructor, the compiler, in effect, inserts a simple "super();".

The class A constructor is, in effect:

    public A(int t)  {
        super();
        System.out.println("A's constructor is invoked");
    }

Obviously, there must be a B() constructor for this to work.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
1

Put simply, the first line in the subclass constructor is the call to super().
Here is what happens behind the scenes.

{
public A(int);
  Code:
   Stack=2, Locals=2, Args_size=2
   0:   aload_0
   1:   invokespecial   #1; //Method B."<init>":()V
   4:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   7:   ldc     #3; //String A's constructor is invoked
   9:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   12:  return
  LineNumberTable:
   line 11: 0
   line 13: 4
   line 14: 12

}

As you can see line 1 is calling B.init() which is the default constructor (no args) .

That is reason why you need a no-args constructor in B.

Ajay George
  • 11,759
  • 1
  • 40
  • 48
  • so its basically just the rule in java then? Your subclass has to be able to call on a no arg constructor in its superclass or the alternative is to do super(t) in class A.? – John W Jan 10 '13 at 06:40
  • but then if super(t) is in class A the no arg constructor is not required in class B. Is the rule then that class A has to have a connection to its super class B somehow? – John W Jan 10 '13 at 07:10