Why default constructor is required in a parent class if it has an argument-ed constructor?

Java

Java Problem Overview


Why default constructor is required(explicitly) in a parent class if it has an argumented constructor

class A {    
  A(int i){    
  }
}

class B extends A {
}

class Main {    
  public static void main(String a[]){
    B b_obj = new B();
  }
}

This will be an error.

Java Solutions


Solution 1 - Java

There are two aspects at work here:

  • If you do specify a constructor explicitly (as in A) the Java compiler will not create a parameterless constructor for you.

  • If you don't specify a constructor explicitly (as in B) the Java compiler will create a parameterless constructor for you like this:

      B()
      {
          super();
      }
    

(The accessibility depends on the accessibility of the class itself.)

That's trying to call the superclass parameterless constructor - so it has to exist. You have three options:

  • Provide a parameterless constructor explicitly in A
  • Provide a parameterless constructor explicitly in B which explicitly calls the base class constructor with an appropriate int argument.
  • Provide a parameterized constructor in B which calls the base class constructor

Solution 2 - Java

Why default constructor is required(explicitly) in a parent class if it has an argumented constructor

I would say this statement is not always correct. As ideally its not required.

The Rule is : If you are explicitly providing an argument-ed constructer, then the default constructor (non-argumented) is not available to the class.

For Example :   
class A {    
  A(int i){    
  }
}

class B extends A {
}

So when you write

B obj_b = new B();

It actually calls the implicit constructor provided by java to B, which again calls the super(), which should be ideally A(). But since you have provided argument-ed constructor to A, the default constructor i:e A() is not available to B().

That's the reason you need A() to be specifically declared for B() to call super().

Solution 3 - Java

Every subclass constructor calls the default constructor of the super class, if the subclass constructor does not explicitly call some other constructor of the super class. So, if your subclass constructor explicitly calls a super class constructor that you provided (with arguments), then there is no need of no arguments constructor in the super class. So, the following will compile:

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

But the following will not compile, unless you explicitly provide no args constructor in the super class:

class B extends A{
     int i; 
     B(int m){
        i=m;
     }
}

Solution 4 - Java

Assuming that you meant to write class B extends A:

Every constructor has to call a superclass constructor; if it does not the parameterless superclass constructor is called implicitly.

If (and only if) a class declares no constructor, the Java compiler gives it a default constructor which takes no parameters and calls the parameterless constructor of the superclass. In your example, A declares a constructor and therefor does not have such a default constructor. Class B does not declare a constructor, but cannot get a default constructor because its superclass does not have a parameterless constructor to call. Since a class must always have a constructor, this is a compiler error.

Solution 5 - Java

Why default constructor is required(explicitly) in a parent class if it 
has an argumented constructor

Not necessarily!

Now in your class B

class B extends A {
}

you have not provided any constructor in Class B so a default constructor will be placed. Now it is a rule that each constructor must call one of it's super class constructor. In your case the default constructor in Class B will try to call default constructor in class A(it's parent) but as you don't have a default constructor in Class A(as you have explicitly provided a constructor with arguments in class A you will not have a default constructor in Class A ) you will get an error.

What you could possibly do is

Either provide no args constructor in Class A.

A()
{
  //no arg default constructor in Class A
}

OR

Explicitly write no args constructor in B and call your super with some default int argument.

B()
{
    super(defaultIntValue);
}

Bottom line is that for an object to be created completely constructors of each parent in the inheritance hierarchy must be called. Which ones to call is really your design choice. But in case you don't explicitly provide any java will put default constructor super() call as 1st line of each of your sub class constructors and now if you don't have that in superclass then you will get an error.

Solution 6 - Java

There are a few things to be noted when using constructors and how you should declare them in your base class and super class. This can get somewhat confusing solely because there can be many possibilities of the availability or existence of constructors in the super class or base class. I will try to delve into all the possibilities:

  • If you explicitly define constructors in any class(base class/super class), the Java compiler will not create any other constructor for you in that respective class.

  • If you don't explicitly define constructors in any class(base class/super class), the Java compiler will create a no-argument constructor for you in that respective class.

  • If your class is a base class inheriting from a super class and you do not explicitly define constructors in that base class, not only will a no-argument constructor be created for you (like the above point) by the compiler, but it will also implicitly call the no-argument constructor from the super class.

     class A 
     {
        A() 
      {
       super();
      }
     }
    
  • Now if you do not explicity type super(), (or super(parameters)), the compiler will put in the super() for you in your code.

  • If super() is being called (explicitly or implicitly by the compiler) , the compiler will expect your superclass to have a constructor without parameters. If it does not find any constructor in your superclass without parameters, it will give you a compiler error.

  • Similary if super(parameters) is called, the compiler will expect your superclass to have a constructor with parameters(number and type of parameters should match). If it does not find such a constructor in your superclass, it will give you a compiler error. ( Super(parameters) can never be called implicitly by the compiler. It has to be explicitly put in your code if one is required.)

We can summarize a few things from the above rules

  • If your superclass only has a constructor with parameters and has no no-argument constructor, you must have an explicit super(parameters) statement in your constructor. This is because if you do not do that a super() statement will be implicitly put in your code and since your superclass does not have a no-argument constructor, it will show a compiler error.
  • If your superclass has a constructor with parameters and another no-argument constructor, it is not necessary to have an explicit super(parameters) statement in your constructor. This is because a super() statement will be implicitly put in your code by the compiler and since your superclass has a no-argument constructor, it will work fine.
  • If your superclass only has a no-argument constructor you can refer to the point above as it is the same thing.

Another thing to be noted is if your superclass has a private constructor, that will create an error when you compile your subclass. That is because if you don't write a constructor in your subclass it will call the superclass constructor and the implicit super() will try to look for a no-argument constructor in the superclass but will not find one.

Solution 7 - Java

Say this compiled, what would you expect it to print?

class A{
  A(int i){
    System.out.println("A.i= "+i);
  }
}

class B extends A {
  public static void main(String... args) {
    new B();
  }
}

When A is constructed a value for i has to be passed, however the compiler doesn't know what it should be so you have specify it explicitly in a constructor (any constructor, it doesn't have to be a default one)

Solution 8 - Java

Of course its an error if written like this it's not JAVA.

If you would have use JAVA syntax it wouldn't be an error.

Class A and B knows nothing about each other if in separate files/packages.

Class A doesn't need a default constructor at all it works fine with only a parameter constructor.

If B extends A you simple use a call to super(int a) in B's constructor and everything is fine. for constructors not calling a super(empty/or not) extending a super class the compiler will add a call to super().

For further reading look at Using the Keyword super

Solution 9 - Java

I would guess that its because when you have an empty parameter list the super variable can't be instantiated. With empty parameter list I mean the implicit super() the compiler could add if the super class had a nonparametric constructor.

For example if you type:

int a;
System.out.print(a);

You will get an error with what I think is the same logic error.

Solution 10 - Java

When we have parameter constructor. we explicit bound to consumer by design. he can not create object of that class without parameter. some time we need to force user to provide value. object should be created only by providing parameter(default value).

class Asset
{
    private int id;
    public Asset(int id)
    {
        this.id = id;
    }
}

class Program
{
    static void Main(string[] args)
    {
        /* Gives Error - User can not create object. 
         * Design bound
         */
        Asset asset1 = new Asset();/* Error */
    }
}

Even child class can not create. hence it is behavior of good design.

Solution 11 - Java

When extending a class, the default superclass constructor is automatically added.

public class SuperClass {
}

public class SubClass extends SuperClass {
   public SubClass(String s, Product... someProducts) {
      //super(); <-- Java automatically adds the default super constructor
   }
}

If you've overloaded your super class constructor, however, this takes the place of the default and invoking super() will thus cause a compile error as it is no longer available. You must then explicitly add in the overloaded constructor or create a no-parameter constructor. See below for examples:

public class SuperClass {
   public SuperClass(String s, int x) {
     // some code
   }
}

public class SubClass extends SuperClass {
   public SubClass(String s, Product... someProducts) {
      super("some string", 1);
   }
}

OR...

public class SuperClass {
   public SuperClass() {
     // can be left empty.
   }
}

public class SubClass extends SuperClass {
   public SubClass(String s, Product... someProducts) {
      //super(); <-- Java automatically adds the no-parameter super constructor
   }
}

Solution 12 - Java

Because if you want to block creation of objects without any data in it, this is one good way.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionbharanitharanView Question on Stackoverflow
Solution 1 - JavaJon SkeetView Answer on Stackoverflow
Solution 2 - JavaSwagatikaView Answer on Stackoverflow
Solution 3 - JavaKale KakhianiView Answer on Stackoverflow
Solution 4 - JavaMichael BorgwardtView Answer on Stackoverflow
Solution 5 - JavaAniket ThakurView Answer on Stackoverflow
Solution 6 - JavaSuvajit ChakrabartyView Answer on Stackoverflow
Solution 7 - JavaPeter LawreyView Answer on Stackoverflow
Solution 8 - JavaFarmorView Answer on Stackoverflow
Solution 9 - JavaFarmorView Answer on Stackoverflow
Solution 10 - JavaJugal PanchalView Answer on Stackoverflow
Solution 11 - JavaArielle AdamsView Answer on Stackoverflow
Solution 12 - JavaAshish Agrawal YodleeView Answer on Stackoverflow