Tuesday, July 03, 2012

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: cannot find symbol constructor in B If we don't have argument constructor the compiler will insert super() the first line in derived class constructor. Since the parent has parameter(arguments) constructor, it supersedes the default constructor in A, the compiler could not find the default constructor per error showing therefore so we need to insert the default constructor.
So class A will have 2 constructors: default A(){} and A(int i){}.
2 ways to fix it
- has a default constructor in parent class A
- has a super(int) in B constructor
class A {    
  A(int i){    
  }

  A(){}     //insert the default constructor in the base class, derived class unchanged 
}
class B extends A {
}
class Main {    
  public static void main(String a[]){
    B b_obj = new B();
  }
}
 

class A {    
  A(int i){    
  } 
}
class B extends A {

  B(int i) {    // add constructor for B with super(i) in the 1st line

  super(i); 

  }
}
class Main {    
  public static void main(String a[]){
    B b_obj = new B(2); //constructor has a value
  }
}
Same thing in C++ you need to create a default constructor for base class if the base class has arguments constructor as long as this argument/parameter constructor is exist the compile will not create default constructor. In Java you can use "super" keyword to call parameter constructor is must be the first line of derived/child constructor. To be compatible for both C++ and Java it is always good to have the parent default constructor.
class A { 
 int i;
  public:  
  A(){}  
  A(int i){}   //A(int i) no default constructor you have to create one above A(){} like Java
};
class B : public A {
  public:
};

int  main(){
   B *b_obj = new B;  // for B compiler will use default constructor B(){} requires A(){}
}
See this for the full behaviors of C++ WRT constructors: http://en.wikipedia.org/wiki/Default_constructor
if you specify a constructor, the compiler will not create a default one for you. The compiler will define a default ctor if and only if you don't explicitly declare any ctors. It is confusing when there is a parent and child class (derived class). In the above examples, we think that the compiler will generate the default constructor for the child class since there is no constructor is defined so it creates a default constructor for the child but when the object is created in the child class, the parent constructor is called first then the child constructor, this is where the error happens because it could not find the default constructor in the parent class.
This rule applies to Java and C++ as well.
Another way to do is let the child class initializes the base class ctor then no default ctor at base class as long as the compiler know there is one ctor is defined so it does not look for a default ctor. This is the case there is no source code for base class just a library to link and it can be set in the derived class (child class)
#include <iostream>
using namespace std;

class A { 
 int i;
  public:  
  //A(){}  
  A(int i){}   //A(int i) no default constructor you have to create one above A(){} like Java
};
class B : public A {
 public:
 int j;
 B():A(j){}   // derived class initialize the base class constructor
};

int  main(){
   B *b_obj = new B;
}

No comments: