What exactly is a default constructor — can you tell me which one of the following is a default constructor and what differentiates it from any other constructor?
public Module() {
this.name = "";
this.credits = 0;
this.hours = 0;
}
public Module(String name, int credits, int hours) {
this.name = name;
this.credits = credits;
this.hours = hours;
}
Neither of them. If you define it, it's not the default.
The default constructor is the no-argument constructor automatically generated unless you define another constructor. Any uninitialised fields will be set to their default values. For your example, it would look like this assuming that the types are String, int and int, and that the class itself is public:
public Module()
{
super();
this.name = null;
this.credits = 0;
this.hours = 0;
}
This is exactly the same as
public Module()
{}
And exactly the same as having no constructors at all. However, if you define at least one constructor, the default constructor is not generated.
Reference: Java Language Specification
If a class contains no constructor declarations, then a default constructor with no formal parameters and no throws clause is implicitly declared.
Clarification
Technically it is not the constructor (default or otherwise) that default-initialises the fields. However, I am leaving it the answer because
the question got the defaults wrong, and
the constructor has exactly the same effect whether they are included or not.
A default constructor is created if you don't define any constructors in your class. It simply is a no argument constructor which does nothing. Edit: Except call super()
public Module(){
}
A default constructor is automatically generated by the compiler if you do not explicitly define at least one constructor in your class. You've defined two, so your class does not have a default constructor.
Per The Java Language Specification Third Edition:
8.8.9 Default Constructor
If a class contains no constructor
declarations, then a default
constructor that takes no parameters
is automatically provided...
Hi. As per my knowledge let me clear the concept of default constructor:
The compiler automatically provides a no-argument, default constructor
for any class without constructors. This default constructor will call
the no-argument constructor of the superclass. In this situation, the
compiler will complain if the superclass doesn't have a no-argument
constructor so you must verify that it does. If your class has no
explicit superclass, then it has an implicit superclass of Object,
which does have a no-argument constructor.
I read this information from the Java Tutorials.
Java provides a default constructor which takes no arguments and performs no special actions or initializations, when no explicit constructors are provided.
The only action taken by the implicit default constructor is to call the superclass constructor using the super() call. Constructor arguments provide you with a way to provide parameters for the initialization of an object.
Below is an example of a cube class containing 2 constructors. (one default and one parameterized constructor).
public class Cube1 {
int length;
int breadth;
int height;
public int getVolume() {
return (length * breadth * height);
}
Cube1() {
length = 10;
breadth = 10;
height = 10;
}
Cube1(int l, int b, int h) {
length = l;
breadth = b;
height = h;
}
public static void main(String[] args) {
Cube1 cubeObj1, cubeObj2;
cubeObj1 = new Cube1();
cubeObj2 = new Cube1(10, 20, 30);
System.out.println("Volume of Cube1 is : " + cubeObj1.getVolume());
System.out.println("Volume of Cube1 is : " + cubeObj2.getVolume());
}
}
General terminology is that if you don't provide any constructor in your object a no argument constructor is automatically placed which is called default constructor.
If you do define a constructor same as the one which would be placed if you don't provide any it is generally termed as no arguments constructor.Just a convention though as some programmer prefer to call this explicitly defined no arguments constructor as default constructor. But if we go by naming if we are explicitly defining one than it does not make it default.
As per the docs
If a class contains no constructor declarations, then a default constructor with no formal parameters and no throws clause is implicitly declared.
Example
public class Dog
{
}
will automatically be modified(by adding default constructor) as follows
public class Dog{
public Dog() {
}
}
and when you create it's object
Dog myDog = new Dog();
this default constructor is invoked.
default constructor refers to a constructor that is automatically generated by the compiler in the absence of any programmer-defined constructors.
If there's no constructor provided by programmer, the compiler implicitly declares a default constructor which calls super(), has no throws clause as well no formal parameters.
E.g.
class Klass {
// Default Constructor gets generated
}
new Klass(); // Correct
-------------------------------------
class KlassParameterized {
KlassParameterized ( String str ) { //// Parameterized Constructor
// do Something
}
}
new KlassParameterized(); //// Wrong - you need to explicitly provide no-arg constructor. The compiler now never declares default one.
--------------------------------
class KlassCorrected {
KlassCorrected (){ // No-arg Constructor
/// Safe to Invoke
}
KlassCorrected ( String str ) { //// Parameterized Constructor
// do Something
}
}
new KlassCorrected(); /// RIGHT -- you can instantiate
If a class doesn't have any constructor provided by programmer, then java compiler will add a default constructor with out parameters which will call super class constructor internally with super() call. This is called as default constructor.
In your case, there is no default constructor as you are adding them programmatically.
If there are no constructors added by you, then compiler generated default constructor will look like this.
public Module()
{
super();
}
Note: In side default constructor, it will add super() call also, to call super class constructor.
Purpose of adding default constructor:
Constructor's duty is to initialize instance variables, if there are no instance variables you could choose to remove constructor from your class. But when you are inheriting some class it is your class responsibility to call super class constructor to make sure that super class initializes all its instance variables properly.
That's why if there are no constructors, java compiler will add a default constructor and calls super class constructor.
When we do not explicitly define a constructor for a class, then java creates a default constructor for the class. It is essentially a non-parameterized constructor, i.e. it doesn't accept any arguments.
The default constructor's job is to call the super class constructor and initialize all instance variables. If the super class constructor is not present then it automatically initializes the instance variables to zero. So, that serves the purpose of using constructor, which is to initialize the internal state of an object so that the code creating an instance will have a fully initialized, usable object.
Once we define our own constructor for the class, the default constructor is no longer used. So, neither of them is actually a default constructor.
When you don’t define any constructor in your class, compiler defines default one for you, however when you declare any constructor (in your example you have already defined a parameterized constructor), compiler doesn’t do it for you.
Since you have defined a constructor in class code, compiler didn’t create default one. While creating object you are invoking default one, which doesn’t exist in class code. Then the code gives an compilation error.
When you create a new Module object, java compiler add a default constructor for you because there is no constructor at all.
class Module{} // you will never see the default constructor
If you add any kind of constructor even and non-arg one, than java thing you have your own and don't add a default constructor anymore.
This is an non-arg constructor that internelly call the super() constructor from his parent class even you don't have one. (if your class don't have a parent class than Object.Class constructor will be call)
class Module{
Module() {} // this look like a default constructor but in not.
}
A default constructor does not take any arguments:
public class Student {
// default constructor
public Student() {
}
}
I hope you got your answer regarding which is default constructor.
But I am giving below statements to correct the comments given.
Java does not initialize any local variable to any default value. So
if you are creating an Object of a class it will call default
constructor and provide default values to Object.
Default constructor provides the default values to the object like 0,
null etc. depending on the type.
Please refer below link for more details.
https://www.javatpoint.com/constructor
Related
I've been working with java and learning i've a question regarding default constructor in a class. Why does it call super (constructor of Object class.I know it does constructor chaining)?. For what reasons it is required ?. If I define a class like this
MyClass
{
public MyClass()
{
}
}
the compiler adds super in the constructor.
public MyClass()
{
super();
}
P.S I've tried googling and have read Oracle Doc but couldnt find the answer .why?
Thanks for your time.
Every constructor must call either a different constructor of the same class or a constructor of its direct super class. The call to the super class constructor is added implicitly if you don't call it explicitly.
Since an instance of a class inherits the state of its ancestors, it must initialize it by calling the constructors of its ancestors.
In your case, your MyClass is a direct sub-class of Object, so your constructor must call the constructor of Object.
A class always is a chain of classes, and always ending with Object (where Object is the only exception; it has no super class).
If a new instance is created, than all the classes in the chain must be initialized, otherwise their state would be undefined. This also applies to classes that seem not to need initialization (like Object).
Initialization is done partially implicitly (variables getting their default values) and for the other part by always calling a constructor in the class.
Why does it call super (constructor of Object class.I know it does
constructor chaining)?. For what reasons it is required ?
Consider this example:
class A {
protected String s;
A () {
this.s = "hello";
}
}
class B extends A {
public String get() {
return s;// s is inherited from A
}
}
// A's default constructor is invoked here
System.out.println(new B().get());// prints hello
Lets say for now java does not include the super() in the constructor.
// A's default constructor is not invoked here
System.out.println(new B().get());// prints null
It gives null as the default value for class types. Since A's constructor is not invoked for new instance of B the instance variable of A is not initialized.
It seems not making sense for sub class is forced to call constructor of base class expicitly. If user can create its own constructor and not limited to base class, it will be more flexible. Anyone can tell me why this behavior is forced in JAVA? What is the good point for this?
class A
{
public A(String s)
{
System.out.println(s);
System.out.println("BASE parameter constructor");
}
}
class C extends A
{
public C(String s)
{
super(s);// why here compiler force to call constructor of base class
System.out.println("Sub parameter constructor");
}
}
because base class does not have a no-arg constructor which is called by default from subclass.
If you just do like this
public C(String s)
{
System.out.println("Sub parameter constructor");
}
Then a default call to super constructor will be placed there and it will become
public C(String s)
{
super();
System.out.println("Sub parameter constructor");
}
But compiler does not provide a no-arg constructor as you have already defined a parameterized constructor as it is provided only when no other constructors are provided for the class.
When you create a new class, you do not have to specify a constructor. Java implicitly creates one for you during compile. Such a constructor is called a default constructor.
If your class doesn't specify a constructor, and if you subclass that class, similarly, you would not have to explicitly provide a constructor.
However, when you start to have a constructor in your class, then Java doesn't create a default constructor for you. If your constructor takes in at least one input parameter, then it is necessary for your subclass to call your parent class's constructor.
8.8.9. Default Constructor
If a class contains no constructor declarations, then a default
constructor with no formal parameters and no throws clause is
implicitly declared.
If the class being declared is the primordial class Object, then the
default constructor has an empty body. Otherwise, the default
constructor simply invokes the superclass constructor with no
arguments.
It is a compile-time error if a default constructor is implicitly
declared but the superclass does not have an accessible constructor
(§6.6) that takes no arguments and has no throws clause.
I am getting the error mentioned in title in the following code. Please tell me why am I getting this error, although i haven't called a default constructor MyNumber() from the superclass any where, and how to fix it.
package referencereturntype;
public class MyNumber {
String num;
public MyNumber(String str){
num=str;
}
public static void main (String [] args){
MyNumber my_num= new MyNumber("+2");
System.out.println("Success! The object of the class itself is successfully returned from retOb(). The object now contains the string : " + retOb(my_num).num);
}
public static SubMyNumber retOb(MyNumber my_num){
SubMyNumber sub_my_num= new SubMyNumber("-50");
sub_my_num.nums=my_num.num;
return sub_my_num;
}
}
public class SubMyNumber extends MyNumber {
String nums;
public SubMyNumber( String strs){
nums=strs;
}
}
Thanks in advance.
You must call a constructor from the base class when instantiating the derived class.
If you don't, Java will implicitly call the default constructor.
If there is no default constructor, you get that error.
From JLS 8.8.7
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();",
Since there is no no-args constructor in the super-class the constructor with the String argument must be explicitly invoked
As you don't have default constructor you have to call it explicit.
public class SubMyNumber extends MyNumber {
String nums;
public SubMyNumber( String strs){
super(null); // Or the value you want to superClass
this.nums=strs;
}
When a superclass does not have a default empty constructor, then you must explicitly call super from your subclass's constructor.
The thing is if there is no constructor defined in your class, java internally provides a default constructor which is further used to create objects. In case you provide you own constructor (can be either default or parameterized), the Java provided hidden constructor gets lost.
In your case, you have provided a parameterized constructor in 'MyNumber'. Thus the hidden default constructor is no more available to be called from the child class's constructor (super()).
The only change you need to do in this code is to either
1. Give your own default constructor in addition to the parameterized constructor which is already there. Now, when the default constructor of class 'MyNumber' shall be INTERNALLY called from the first LOC in the parameterized constructor of 'SubMyNumber', there won't be any error.
Or you can change the parameterized constructor of subn class like this
public SubMyNumber(String strs){
super(strs);
nums=strs;
}
This way you shall explicitly set the parameterized constructor of MyNumber to be called which is already defined.
I was wondering how to use a superclass constructor in a subclass but need to instantiate fewer attributes in the subclass. Below are the two classes. I'm not even sure if I'm doing things right currently. In the second class, there's an error that says "Implicit super constructor PropertyDB() is undefined. Must explicitly invoke another constructor." Note that this code is obviously incomplete and there is code that's commented out.
public abstract class PropertyDB {
private int hectares;
private String crop;
private int lotWidth;
private int lotDepth;
private int buildingCoverage;
private int lakeFrontage;
private int numBedrooms;
private int listPrice;
//public abstract int getPricePerArea();
//public abstract int getPricePerBuildingArea();
public PropertyDB(int newHectares, String newCrop, int newLotWidth, int newLotDepth,
int newBuildingCoverage, int newLakeFrontage, int newNumBedrooms, int newListPrice){
hectares = newHectares;
crop = newCrop;
lotWidth = newLotWidth;
lotDepth = newLotDepth;
buildingCoverage = newBuildingCoverage;
lakeFrontage = newLakeFrontage;
numBedrooms = newNumBedrooms;
listPrice = newListPrice;
}
}
public class FarmedLand extends PropertyDB{
public FarmedLand(int newHectares, int newListPrice, String newCorn){
//super(270, 100, "corn");
hectares = newHectares;
listPrice = newListPrice;
corn = newCorn;
}
}
implicit constructor PropertyDB() exists only if you do not define any other constructors, in which case you will have to explicitly define PropertyDB() constructor.
The reason you see this error "Implicit super constructor PropertyDB() is undefined. Must explicitly invoke another constructor." is that in your public FarmedLand(int newHectares, int newListPrice, String newCorn) constructor, super() is automatically called as the first statement, which does not exist in your superclass.
Here's a simplified example:
public class A { }
can be instantiated by using A a = new A() because public A() { } is an implicit constructor of class A.
public class A {
public A(int z) { /* do nothing*/ }
}
can not be instantiated using A a = new A() because by defining an explicit constructor public A(int z) the implicit one is no longer available.
Moving onto constructors and inheritance, from Java Language Specification section 8.8.7:
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 is implicitly assumed by the compiler to begin with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments.
So in your case the first statement executed in public FarmedLand(int newHectares, int newListPrice, String newCorn) constructor is an implicit call to super();, which in your case is not defined implicitly (there's already a public PropertyDB(int, String, ...) constructor defined) or explicitly (it's not in the source code)
When you have a derived class which extends a base class, the base class always gets constructed before the derived class. If you don't explicitly specify which constructor to use for the base class (like in your example), Java assumes you meant the parameterless constructor (in your case the PropertyDB() constructor).
But wait - PropertyDB doesn't have a parameterless constructor! So your only option is to use super so the Java compiler knows which constructor to call for the base class. In your case, there's only one constructor to choose from, so you have to use it with all 8 arguments. If you want to use less arguments, you either have to specify "default" values (like pass a 0), or else define more constructors for PropertyDB which take fewer arguments.
The error you're witnessing is due to the fact that the PropertyDB class doesn't have a default (no-arguments) constructor. Either create it in PropertyDB or call the existing superclass constructor PropertyDB(int newHectares, String newCrop, int newLotWidth, int newLotDepth, int newBuildingCoverage, int newLakeFrontage, int newNumBedrooms, int newListPrice) from the FarmedLand constructor using super.
Use super(newHectares, newCorn, 0, 0, 0, 0, newListPrice); instead. 0 is the default value of the int anyway.
Your superclass only has one constructor, so your subclass constructor must call it. There's no way around this: the superclass has (for example) a lotWidth field, so the subclass necessarily has that field, and the superclass initializes that field in its constructor, so it will necessarily be initialized in the subclass.
So, unless you modify the superclass in some way, you're going to have to call super(...) as the very first thing in the subclass constructor, specifying values for all its parameters.
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.
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
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;
}
}
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().
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.
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.
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.
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)
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
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.
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.
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
}
}
Because if you want to block creation of objects without any data in it, this is one good way.