I have two class :-
import java.lang.*;
class A {
public A(int number) {
System.out.println("HI I AM INSIDE PARENT CONSTRUCTOR");
}
}
class B extends A {
public static void main(String[] args) {
A obj = new A(10);
}
}
Error:- Implicit super constructor A() is undefined for default constructor. Must define an explicit constructor.
The problem is that you have no constructor declared in B, so the compiler is supplying the default constructor, which in effect looks like this:
B() {
super();
}
Since A has no constructor accepting zero parameters, B can't be compiled. You'll need to add a constructor to B that calls super(int), or you'll need to add a zero-parameters constructor to A.
Principle
A subclass constructor has to invoke the parent constructor.
By default, a no arg constructor is generated by the compiler if you don't declare one.
Important detail : this generated constructor invokes the parent constructor with a no arg invocation.
Your case
You don't declare a constructor in B.
So a default no arg constructor of B is generated :
This constructor is :
B(){
super();
}
but it cannot invoke the parent constructor as it declares one parameter :
public A(int number)
So the compiler emits this error :
Implicit super constructor A() is undefined for default constructor.
Must define an explicit constructor.
To solve your problem, declare a constructor in the subclass that invokes explicitly the parent constructor with the expected argument :
public B(int number) {
super(number);
}
I think you're missing the default constructor in your A class.
See this answer for further explanation.
You have given your own constructor for A having arguments of int. now you need to add a constructor on your own to the class B as well.
public B(int number) {
super(number);
}
When you don't define a constructor in Java, you get an implicit default constructor. When you define a constructor, then the default constructor is not there anymore. So, when you have something like:
Class A {
}
this is equivalent to:
Class A {
A() {
super();
}
}
In your case, class B is calling the default constructor of A, but because A already defined another constructor, the default constructor is then not there anymore, unless you define it explicitly.
Add constructor B(int):
import java.lang.*;
class A {
public A(int number) {
System.out.println("HI I AM INSIDE PARENT CONSTRUCTOR");
}
}
class B extends A {
public B(int number) {
super(number);
}
public static void main(String[] args) {
A obj = new A(10);
}
}
Add:
public B(int number) {
super(number);
}
Cause you have defined a constructor with arguments in parent class,so the compiler won't call the default constructor without arguments.In order to instance parent class before subclass initializing,you have to call parent's explicit constructor in subclass.
Related
I have doubt regarding printing of superclass constructor statement even when I have not used super() keyword in subclass.
class A
{
int i;
A()
{
System.out.println("A's constructor");
}
}
class B extends A
{
int i;
B(int a , int b)
{
super.i=a;
i=b;
}
void show()
{
System.out.println(super.i);
System.out.println(i);
}
}
class UseSuper
{
public static void main(String[] args)
{
B b=new B(1,2);
b.show();
}
}
The output of my program is:
A's constructor
1
2
I am unable to understand why I am getting A's constructor printed on my console?
Check the following lines from https://docs.oracle.com/javase/tutorial/java/IandI/super.html
Note: If a constructor does not explicitly invoke a superclass
constructor, the Java compiler automatically inserts a call to the
no-argument constructor of the superclass. If the super class does not
have a no-argument constructor, you will get a compile-time error.
Object does have such a constructor, so if Object is the only
superclass, there is no problem.
If a subclass constructor invokes a constructor of its superclass,
either explicitly or implicitly, you might think that there will be a
whole chain of constructors called, all the way back to the
constructor of Object. In fact, this is the case. It is called
constructor chaining, and you need to be aware of it when there is a
long line of class descent.
I hope, it clears your doubts.
[Update]
Posting this update to clear OP's doubts he has mentioned in his comment below.
The following code won't compile because implicit super constructor A() has not been defined and we have also not defined it explicitly. Note that the implicit super constructor A() is automatically defined when there is no other constructor with arguments have been defined.
class A {
int i;
A(int x,int y){
}
}
class B extends A {
int i;
B(int a, int b) {
super.i = a;
i = b;
}
void show() {
System.out.println(super.i);
System.out.println(i);
}
}
public class UseSuper {
public static void main(String[] args) {
B b = new B(1, 2);
b.show();
}
}
[Another Update]
Posting this update to clear OP's another doubt which he has mentioned in his comment below.
The following code too won't compile because the super constructor A() has been declared as private preventing the child class constructor to call it.
class A {
int i;
private A() {
System.out.println("A's constructor");
}
}
class B extends A {
int i;
B(int a, int b) {
super.i = a;
i = b;
}
void show() {
System.out.println(super.i);
System.out.println(i);
}
}
class UseSuper {
public static void main(String[] args) {
B b = new B(1, 2);
b.show();
}
}
When a class extends another class, it is crucial to first call the constructor of the parent class and initialize it, before calling the constructor of the current class.
Even when not visually calling super() in any part of your constructor, Java itself calls the constructor of class A.
If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass. If the superclass does not have a no-argument constructor, you will get a compile-time error. Object does have such a constructor, so if Object is the only superclass, there is no problem.
In other words, constructor B(int a , int b) calls constructor A() implicitly. In IDE, just change A() to A(int i) and you'll see an error message for constructor B(int a , int b) like "Implicit super constructor A() is undefined. Must explicitly invoke another constructor".
This question already has answers here:
Why is super class constructor always called [duplicate]
(3 answers)
Closed 3 years ago.
If I have a subclass that doesn't have a constructor defined but in the superclass there is one defined, will the subclass use that constructor when the subclass object is instantiated?
Does a subclass use parent constructor if one isn't defined in the subclass?
That depends on what you mean by "use." If you mean, does the default constructor for a child class call the parent constructor, then yes, it does (more below). If you mean, is a default constructor matching whatever parameters the parent constructor has created automatically, then no, not in the general case.
When you don't declare any constructors for a child class, the default constructor is supplied for you. It always looks like this
/*same access modifier as the class*/ Child() {
super();
}
Base classes have a default as well, which looks the same but just doesn't have super();.
So if the parent class has a no-arguments constructor (explicitly, or via the default) then the child class's default constructor will successfully use it. But if there's a constructor defined in the parent class that requires an argument, then the child class won't compile, because the super() in the default constructor doesn't match a constructor in the parent class.
Compare this, which works:
public class Parent {
public Parent() { // I could have left this off, since it's the default for a
} // base class; it's here for emphasis
public static void main(String[] args) {
new Child();
}
}
class Child extends Parent {
}
with this (added a String param to the Parent constructor), which fails:
public class Parent {
public Parent(String s) {
}
public static void main(String[] args) {
new Child();
}
}
class Child extends Parent {
}
The second one fails with:
class Child extends Parent {
^
required: String
found: no arguments
reason: actual and formal argument lists differ in length
1 error
If no constructor is written in a class, actually a default constructor is added, which can be seen in the byte code:
class A {
}
will generate code for:
class A extends Object {
A() {
super();
}
}
Every constructor must call a constructor of the parent class as the first statement.
Again here there is an implicit call to super().
class B extends A {
B() {
System.out.println();
}
B(int n) {
System.out.println();
}
}
will generate code for
class B extends A {
B() {
super(); // A()
System.out.println();
}
B(int n) {
super(); // A()
System.out.println();
}
}
This means one can get an error, that no (overloaded) constructor is available for the given argument types.
An other point is, that in general the statement super(); serves no purpose.
Say you have an empty child class that extends the parent:
public class TestChild extends TestParent{
}
And the parent looks like:
public class TestParent {
private String testStr;
public TestParent() {
this.testStr = "I exist in the child class!";
}
public String getTestStr() {
return testStr;
}
public void setTestStr(String testStr) {
this.testStr = testStr;
}
}
And you create an object of the child in the main and print it out with:
TestChild test = new TestChild();
System.out.println(test.getTestStr());
The result will print out:
I exist in the child class!
This happens because the child class will automatically call the no-arg constructor of the super class. So you do not explicitly need a constructor in the child class as it will automatically generate to you a default constructor.
In this program there is no need for a super to reach the superclass's constructor:
class Base{
Base(){
System.out.println("Base");
}
}
public class test2 extends Base{
test2() {
//super();
System.out.print("test2");
}
public static void main(String argv[]){
test2 c = new test2();
}
}
But this program needs super and gives an error at quest1 constructor saying
constructor quest can't be applied to given types: required int, found no arguments
class Quest {
Quest(int y){
System.out.print("A:"+y);
}
}
class Quest1 extends Quest {
Quest1(int x){
//super(x+1);
System.out.print("B:"+x);
}
}
class Test {
public static void main(String argv[]){
Quest1 q = new Quest1(5);
}
}
JLS 8.8.7. Constructor Body
If a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object, then the constructor body implicitly begins with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments.
In
class Base {
Base() {
}
}
public class test2 extends Base {
test2() {
//super();
System.out.print("test2");
}
}
The commented out line is added automatically and since the superclass's no-argument constructor is defined, there is no error.
In the case of
class Quest {
Quest(int y) {
System.out.print("A:"+y);
}
}
class Quest1 extends Quest {
Quest1(int x) {
//super(x+1);
System.out.print("B:"+x);
}
}
The implicit call super() is trying to invoke an undefined constructor in the superclass, which causes the error
Implicit super constructor Quest() is undefined. Must explicitly invoke another constructor.
Uncommenting your explicit constructor call replaces the implicit call and thus the problem is resolved. Alternatively, define a no-argument constructor in the superclass.
You need a call to super() if and only if there's no default constructor (accepting no arguments) for your parent class.
In all other cases (where a constructor with zero arguments exists) you don#t have to code it. It's implicitly called anyway.
These Rules apply:
if your parent class has no constructor at all, it has the default constructor, which takes no arguments -> no need for super();
you parent class declares a constructor with no arguments -> no need for super()
your class has a constructor with arguments but no constructor without arguments -> you need to call one of the defined constructors with mathching arguments via super()
If you create a constructor in super class the you should call the super class constructor (Ex : super()) before the sub class constructor gets call.
I'm very new in Java, and about to ask a fundamental question. Hope you guys could help me. Supposed I have a base classe Super and a derived class Sub, which inheritances from class Super as follows:
public class TestSuperSub {
public static void main(String[] args) {
Super ou = new Sub(5,10);
}
}
class Super {
Super() {
System.out.println("Super()");
}
Super(int x, int y) {
System.out.println("Super(int, int)");
}
}
class Sub extends Super {
public Sub(int x, int y) {
System.out.println("Sub(int, int)");
}
}
The output is
Super()
Sub(int, int)
I understand, that ou calls Sub::Sub(int,int) and therefore, Sub(int, int) is printed. But why is Super() printed, since Super::Super() hasn't never been called?
Could someone please explain it to me.
Thanks a lot!
Cheers
By default, Java will call the no-arg constructor of a super class unless you explicitly call another constructor. If you want to call Super(int, int), you must call it explicitly:
public Sub(int x, int y) {
super(x, y);
System.out.println("Sub(int, int)");
}
But why is Super() printed, since Super::Super() hasn't never been called?
It has, because your Sub constructor is implicitly calling it. It's as if you'd written:
public Sub(int x, int y) {
super();
System.out.println("Sub(int, int)");
}
From section 8.8.7 of the JLS:
The first statement of a constructor body may be an explicit invocation of another constructor of the same class or of the direct superclass (ยง8.8.7.1).
...
It is a compile-time error for a constructor to directly or indirectly invoke itself through a series of one or more explicit constructor invocations involving this.
If a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object, then the constructor body implicitly begins with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments.
If you want to call a different superclass constructor, you need to do that implicitly. When you call a subclass constructor, that will always work its way up through the inheritance hierarchy, executing the body of the superclass constructor before the subclass constructor... indeed, even field initializers in the subclass are only run after the superclass constructor.
Its the very basic fundamental concept in Java. Its the magic of super keyword and constructor chaining.
Go through these links. Hope this would help you understand the concept.
http://docstore.mik.ua/orelly/java-ent/jnut/ch03_04.htm
http://docs.oracle.com/javase/tutorial/java/IandI/super.html
By Default in constructor of sub class
the first line is call base class default constructor (implicitly) if no constructor is mentioned that is **
super();
**
if you write
super(x,y);
then other constructor will be called
Note : First line of constructor is to call base class constructor.
if there is no super class then Object class's constructor is called
When you instantiate a class, all the superclass hierarchy must also be instantiated and it will be done so through the null constructors automatically available for each class.
The following code
public class Superclassing {
public static void main(String[] args) {
new C();
}
Superclassing() { System.out.println("super"); }
}
class A extends Superclassing {
A() { System.out.println("A"); }
}
class B extends A {
B() { System.out.println("B"); }
}
class C extends B {
C() { System.out.println("C"); }
}
outputs
super
A
B
C
It is done so by design as mentioned in Skeet's answer and also here (oddly, it is mentioned before it is explained in 8.8.7):
JLS 8.8.3. Constructor Modifiers
The lack of native constructors is an arbitrary language design choice
that makes it easy for an implementation of the Java Virtual Machine
to verify that superclass constructors are always properly invoked
during object creation.
(emphasis mine.)
class A{
A(){
System.out.println("no-arg constructor in A");
}
A(int a){
System.out.println("parameterized constructor in A");
}
}
class B extends A{
B(){
System.out.println("no-arg constructor in B");
}
B(int b){
//by default during compilation super() keyword will be added in first line of this constructor
System.out.println("paramterized constructor in B");
}
}
public class TestDemo {
public static void main(String[] args) {
B aVar = new B(10);
aVar = new B();
}
}
Output:
// output for first object i.e, new B(10)
no-arg constructor in A
paramterized constructor in B
//output for second object i.e, new B()
no-arg constructor in A
no-arg constructor in B
A super() keyword will be add by default by the compiler during compilation depending on the Object that u create in main method.
I've run this code
public class Redimix extends Concrete{
Redimix(){
System.out.println("r ");
}
public static void main(String[] args) {
new Redimix();
}
}
class Concrete extends Sand{
Concrete() { System.out.print("c "); }
private Concrete(String s) { }
}
abstract class Sand{
Sand(){
System.out.print("s ");
}
}
and it printed out s c r but what I was expecting is that only r my question what is the logical explanation for this?
if a parent base class is an abstract class that has a constructor and then we create another class then extend it to the base class (In our Case Concrete extends Sand) and we then create another class then extend it to the concrete class name (In our case redimix) will all constructors from the hierarchy will be called?(from top to bottom)
A constructor of the superclass is always called as the first action of a constructor.
If you do not explicitly invoke a constructor of the superclass, the default constructor (the "no args" one) is implicitly invoked.
That is correct. The parent object's constructor is always called before the childs. This ensures that the object is in a valid state and that the object that has extended another class can always know what state the object is in.
Here is the code that you provided, after the compiler has inserted the implicit constructor calls in on your behave. Note that super(); is always called first.
public class Redimix extends Concrete{
Redimix(){
super();
System.out.println("r ");
}
public static void main(String[] args) {
new Redimix();
}
}
class Concrete extends Sand{
Concrete() { super(); System.out.print("c "); }
private Concrete(String s) { }
}
abstract class Sand{
Sand(){
super(); // invoking the constructor for java.lang.Object
System.out.print("s ");
}
}
In each constructor, parent constructor is also called.
In every constructor, first statement is always super() which is calling super class constructor except for Object class
You need to understand constructor chaining for this. When you make a call to any constructor all the super class constructors are invoked first. In you constructor definition, if you dont have one compiler will add a no argument call to super class constructor something like this : super();
This is because, all the class in the hierarchy must be build before you actual class, because your class is dependent on its super class.
This class to the super class constructor should always be the first statement in your constructor definition because they must be build before this concerned class. So Object class constructor is always the first to be executed.