Sunday, July 3, 2011

Java Tips: Implicit super constructor ParentClassName() is undefined. Must explicitly invoke another constructor

Introduction

Have you ever encountered such a compilation error and wondered why your constructor is throwing such a weird error?
Well, in order to answer this question let us first go through a brief explanation of how constructors work. Then I shall suggest two alternatives for resolving this problem and finally, I would provide references to some very useful pages, where you can further explore the constructors' issues.

What is a default constructor?

Every class has at least one constructor. If a class does not explicitly declare any constructors, the Java compiler automatically provides a no-argument constructor, called the default constructor.


How does a constructor work?

A Java constructor performs the following functions:

1. It initializes the class variables to default values.
- Numeric types (Byte, short, int, long, float, and double) default to their respective zero values
- Boolean defaults to false
- Char defaults to the null character ('\u0000')- References of any objects default to null

2. It then calls another constructor in the same class "this(...)" or a constructor in the parent class "super(...)".- If an explicit call to another constructor is provided (it must be the first statement of a constructor), then this explicit call is performed.
- Otherwise, an implicit call to the parent class' no-argument constructor super() is performed.

3. It then initializes the class variables to the specified values. (For instance, int var = 10;)

4. Finally, it executes the body of the constructor.


How to fix the compilation error?

Here is an example problem from the many scenarios that can lead to the following complier error:
Implicit super constructor Parent() is undefined. Must explicitly invoke another constructor

Problem:

class Parent {

int parentX = 10;

public Parent(int x) {
parentX = x;
}

}

class Child extends Parent {

int childX;

public Child(int x) {
childX = x;
}

}


From the previous two sections, we now should be able to understand why the compiler is complaining, namely...
- The constructor of the Child class does not contain an explicit call to another constructor.
- Thus, it inserts an implicit call to the super class' no-argument constructor, i.e. Parent().
- The parent class DOES NOT have a default no-argument constructor, because it has defined an explicit constructor, namely Parent(int x).

Solution 1:
Explicitly, declare a no-argument constructor for the Parent class.

class Parent {

int parentX = 10;

public Parent() {
// do any initialization, if necessary
}

public Parent(int x) {
parentX = x;
}

}

class Child extends Parent {

int childX;

public Child(int x) {
childX = x;
}

}


Solution 2:
Add an explicit call to another constructor in the Child class'constructor.


class Parent {

int parentX = 10;

public Parent(int x) {
parentX = x;
}

}

class Child extends Parent {

int childX;

public Child(int x) {
super(x);childX = x;
}

}


Finally,...
Well, some developers (usually beginners) think that invisible code generated by the compiler is confusing, because they don't understand what's going on behind the scenes. But eventually, "almost" every developer appreciates this hidden code generation, because -amongst others- it allows one to write less code. And these are the two faces of the coin!

References
Wikipedia: Constructor (object-oriented programming)
This wikipedia article contains a simple definition of a constructor. It also provides examples for the use of constructors in different programming and scripting languages.
http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)

Java Constructors | Java Beginner
This article illustrates via simple examples the use of constructors, constructor overloading and constructor chaining.
http://www.javabeginner.com/learn-java/java-constructors

Java Notes: Constructors
Java Notes contains a list of very useful Java programming notes by Fred Swartz. In this note, different aspects of a class constructor are covered.
Click here to browse the main index of the Java Notes.
http://leepoint.net/notes-java/oop/constructors/constructor.html

Java Basics: Commentary: Always write super()?
Java Basics is a very nice Java tutorial by Fred Swartz. In this commentary, Fred explains the explicit and implicit calls of super().
Click here to browse the main index of the Java Basics tutorial.
http://leepoint.net/JavaBasics/oop/oop-commentary/oopcom-super.html

3 comments:

  1. What if the Parent classes constructer is not visible? Can you then not use it to extend a class

    ReplyDelete
    Replies
    1. Hey Mattew,
      Sorry for my late reply, but I was on vacation.

      Well, if I understand you correctly, you would like to make the constructor of the parent class "private".

      In this case you have not solved the problem, because once a class defines a constructor - even if private, then the default constructor is not implicitly added to the class. Consequently, you will receive the same compilation error.

      But having a private constructor doesn't mean that the child class cannot extend the Parent class.

      I hope this helps.

      Best regards,
      Samar

      Delete
  2. Hi Samar,

    When I am defining the private constructor in Parent class ,
    i am not able to extend the Parent Class in child class.But as an when i am defining it public I am able to do the same.
    Reason??

    Best Regards,
    Priyanka Goel

    ReplyDelete