52

I have a question about default constructors and inheritance in Java.

Generally, if you write a class and do not include any constructor, Java provides automatically for you a default constructor (one without parameters), which initializes all instance variables of the class (if there are any) with some default values (0, null, or false). If you write a constructor, however, with some parameters, and you don't write any default constructor, then Java does not provide a default constructor. My question is: what is the case with classes, which inherit from other classes - if I write a constructor with some parameters in them, but don't include a default constructor, do they inherit the default constructor of the super class?

msrd0
  • 7,816
  • 9
  • 47
  • 82
user42155
  • 48,965
  • 27
  • 59
  • 60
  • 2
    Does the post need an edit to the line which assumes "Constructor initializes all instance variables of the class (if there are any) with some default values (0, null, or false)." misleading the reader? – Srujan Kumar Gulla Jan 09 '13 at 16:41

11 Answers11

63
  1. If you do not make a constructor, the default empty constructor is automatically created.

  2. If any constructor does not explicitly call a super or this constructor as its first statement, a call to super() is automatically added.

Always.

Flimm
  • 136,138
  • 45
  • 251
  • 267
paulmurray
  • 3,355
  • 1
  • 22
  • 17
  • 2
    Links are broken (thanks, Oracle), here are the new ones: http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.8.9 and http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.8.7 – Stoffe Aug 27 '12 at 09:08
  • 2
    @Stoffe: I've suggested an edit fixing the links thanks to your comments. You can gain reputation by suggesting edits, so why not do that in future? – Flimm Mar 26 '13 at 12:12
  • I'd add that, in case 2, the call to super has no parameters. – LuxDie Dec 04 '17 at 23:57
54

Constructors are not inherited.

Also, the initialization of fields is done by the virtual machine, not the default constructor. The default constructor just invokes the default constructor of the superclass, and the default constructor of Object is empty. The good point of this design is that there is no way to ever access uninitialized fields.

starblue
  • 55,348
  • 14
  • 97
  • 151
  • 1
    Yes, I've just understood this, potyl below has pointed this out. But how (and when) are the fields initialised then? (please, see my comment on the potyl's answer). – user42155 Feb 08 '09 at 11:55
  • Is it the case that when I create the object, then Java automatically gives the default values? But then again, we do create objects with constructors, right? – user42155 Feb 08 '09 at 11:57
  • Yes, it took a while to do the research w.r.t. initialization. – starblue Feb 08 '09 at 12:07
  • Thank you, I have also found a nice article exactly about this - initialization in Java, here: http://www.javaworld.com/javaworld/jw-03-1998/jw-03-initialization.html?page=1 – user42155 Feb 08 '09 at 12:47
  • Note that the default constructor of `Object` isn't *empty*, it's *native*. The constructor is generally responsible for things like memory allocation. – chrylis -cautiouslyoptimistic- Feb 13 '15 at 15:58
  • @chrylis No, that's wrong. There is no constructor declaration in the source code of java.lang.Object (I just looked). The Java language specification says in 8.8.9: "If the class being declared is the primordial class Object, then the default constructor has an empty body." Memory allocation is done by the virtual machine. – starblue Feb 13 '15 at 22:22
11

Unless you use super(...) a constructor calls the empty constructor of its parent. Note: It does this on all you classes, even the ones which extend Object.

This is not inheriting, the subclasses don't get the same constructors with the same arguments. However, you can add constructors which call one of the constructors of the super class.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • With "empty constructor" you mean the default constructor, right? – user42155 Feb 08 '09 at 11:33
  • And what if the parent does not have a default constructor? – user42155 Feb 08 '09 at 11:33
  • Here I mean a constructor with no arguments. Typically the default constructor is one which is not defined at all. You can define a constructor with no arguments. – Peter Lawrey Feb 08 '09 at 11:39
  • If the parent does not have a constructor with no arguments, you must call super(...) for a valid constructor in the super class. – Peter Lawrey Feb 08 '09 at 11:40
  • You mean for a "valid constructor in the " SUB (derived) class ? – user42155 Feb 08 '09 at 11:49
  • Btw, I think we call a constructor "default", if it does not have any arguments (parameters) - it doesn't matter whether you define it, or Java. (?) – user42155 Feb 08 '09 at 11:52
  • It seems that I am wrong - a constructor without parameters (or arguments) is called "a non-argument constructor", and the "default" constructor is the one, which is provided automatically by Java, if you don't write any constructor in the class. It is a non-argument constructor.I have read this: – user42155 Feb 08 '09 at 12:51
  • here: http://www.javaworld.com/javaworld/jw-03-1998/jw-03-initialization.html?page=1 – user42155 Feb 08 '09 at 12:51
6

The basic rule is a call (or invocation) to a constructor should be the first statement that JVM needs to execute,

So when you have a super class with only parameterized constructor and no default constructor, and base class has no explicit call to the parameterized constructor of the super class, JVM provides the super(); call which throws error as there is no default constructor for the super class, so either we provide a default constructor in the super class or we explicitly call the parameterized constructor of the super class in the base class constructor. when we give the explicit call, then JVM doesn't bother to put the line super(); as constructor invocation should be the first statement of the method, which cannot happen (because of our explicit call).

Abhishek Nair
  • 61
  • 1
  • 1
  • i guess it should be good practice to always put default constructor there, if you wanna "over-loaded" constructors. – Jackie Jan 07 '13 at 01:43
6

Section 8.8.9 of the Java Language Specification explains in details what is going on:

If a class contains no constructor declarations, then a default constructor is implicitly declared. The form of the default constructor for a top level class, member class, or local class is as follows:

  • The default constructor has the same accessibility as the class (§6.6).
  • The default constructor has no formal parameters, except in a non-private inner member class, where the default constructor implicitly declares one formal parameter representing the immediately enclosing instance of the class (§8.8.1, §15.9.2, §15.9.3).
  • The default constructor has no throws clauses.
  • 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.

You can see that there is no inheritance going on here: all there is to it is the "compiler magic" with implicitly declared default constructor. The specification also makes it clear that the default constructor is added only when the class has no constructors at all, meaning that the answer to your question is "no": once you give a class a constructor, the access to the default constructor of its superclass is lost.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • referenced link: https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.8.9 – cellepo Aug 25 '16 at 19:50
  • what do you mean by "once you give a class a constructor, the access to the default constructor of its superclass is lost." ? – rooni Nov 12 '18 at 07:45
3

If you provide a constructor then Java will not generate you a default empty constructor. So your derived class will only be able to call your constructor.

The default constructor doesn't initialize your private variables to default values. The proof is that it's possible to write a class that doesn't have a default constructor and has its private members initialized to default values. Here's an example:

public class Test {

    public String s;
    public int i;

    public Test(String s, int i) {
        this.s = s;
        this.i = i;
    }

    public Test(boolean b) {
        // Empty on purpose!
    }

    public String toString() {
        return "Test (s = " + this.s + ", i = " +  this.i + ")";
    }

    public static void main (String [] args) {
        Test test_empty = new Test(true);
        Test test_full = new Test("string", 42);
        System.out.println("Test empty:" + test_empty);
        System.out.println("Test full:"  + test_full);
    }
}
John Topley
  • 113,588
  • 46
  • 195
  • 237
Emmanuel Rodriguez
  • 1,584
  • 10
  • 9
  • That's interesting! I have lived quite a long time with the assumption that if you don't initialize the instance variables in a constructor, then Java does this in the default constructor. So, in this case how are the variables initialized? – user42155 Feb 08 '09 at 11:41
  • Here I have found a nice article about initialization in Java, answering my question: http://www.javaworld.com/javaworld/jw-03-1998/jw-03-initialization.html?page=1 – user42155 Feb 08 '09 at 12:48
  • Creating an object instance requires that the operator "new" allocates memory and invokes a constructor (used for initial logic). Our constructors take care only of the latter. I'm guessing that the first part takes care of the default initialization of the data members while allocating memory. – Emmanuel Rodriguez Feb 08 '09 at 18:22
2

The answer to your question is very simple. Implicitly(Invisible), the first statement in any constructor is 'super();' i.e. the call to super class's no parameter constructor, until you change it explicitly to something like 'this();','this(int)','this(String)','super(int)','super(String)' etc. 'this();' is current class's constructor.

ash
  • 156
  • 3
  • 12
2

Thumb Rule is that Sub Class should call any constructor from the base class. so if you don't have the default const the call the existing one from sub class. other wise implement the empty const in the base class to avoid the compilation problem

Muthu N
  • 21
  • 1
1

There will be compile time error...because Compiler looks for default Constructor he Superclass and if its not there...its an error...and program will not Compile...

Shubhamhackz
  • 7,333
  • 7
  • 50
  • 71
1

When we don't create a constructor Java creates a default constructor automatically. But when we create one or more custom constructors with arguments, Java doesn't create any default constructors. If we create one or more constructors and we want to create an object without any constructor arguments, we have to declare a empty constructor.

xShay
  • 78
  • 3
Thusitha
  • 3,393
  • 3
  • 21
  • 33
  • "...create a object without any constructor We have to declare..." => "...create a object without any constructor **arguments**, we have to declare..." – Bert F Jan 26 '11 at 14:03
0

Any constructor in subclass will call the no argument contructor(or default constructor) of parent class. if you define a parameterized constructor in parent class then you have to explicitly call the parent class constructor with super keyword else it will give the compilation error.

class Alpha 
{ 
    Alpha(int s, int p) 
    { 
        System.out.println("base");
    }

} 

public class SubAlpha extends Alpha 
{ 
    SubAlpha() 
    { 
        System.out.println("derived"); 
    } 
    public static void main(String[] args) 
    { 
        new SubAlpha(); 
    } 
}

The above code will give the compilation error:

prog.java:13: error: constructor Alpha in class Alpha cannot be applied to given types;
    { 
    ^
  required: int,int
  found: no arguments
  reason: actual and formal argument lists differ in length
1 error

The above error occurred because neither we have any no argument constructor/default constructor in parent class nor we are calling the parameterized constructor from sub class.

Now to solve this either call the parameterized constructor like this:

class Alpha 
{ 
    Alpha(int s, int p) 
    { 
        System.out.println("base");
    }

} 

public class SubAlpha extends Alpha 
{ 
    SubAlpha() 
    { 
        super(4, 5); // calling the parameterized constructor of parent class
        System.out.println("derived"); 
    } 
    public static void main(String[] args) 
    { 
        new SubAlpha(); 
    } 
}

Output

base
derived

or

define a no argument constructor in parent class like this:

class Alpha 
{ 
    Alpha(){

    }
    Alpha(int s, int p) 
    { 
        System.out.println("base");
    }

} 

public class SubAlpha extends Alpha 
{ 
    SubAlpha() 
    { 
        System.out.println("derived"); 
    } 
    public static void main(String[] args) 
    { 
        new SubAlpha(); 
    } 
}

output

derived