When is a constructor inherited by subclass - java

public class A {
public A() {
System.out.println("A");
}
}
public class B extends A{
public B() {
System.out.println("B");
}
}
public static void main(String[] args){
B b1 = new B();
Output:
A
B
So what's confusing me is, the Inheritance documentation of Java states that:
Constructors are not members, so they are not inherited by subclasses,
but the constructor of the superclass can be invoked from the
subclass.
From my understanding of that, unless you specifically call for super() in the constructor of class B, it should not print A.
So the question is, why does it print A?

The compiler calls the default constructor (no-arg constructor) of the superclass initially from the subclass constructor. So you don't need to explicitly call it. That's why the line is getting printed above.
If you want to call non-default constructor (constructor with arguments) of superclass, then you would have to explicitly call it form subclass.

Related

Creating same method in both Parent and Child class provides some weird output

In the below code , I have three questions. I know that having same function in both Parent and Child class does not make any sense and not at all a good design. But , since Java is allowing me to do this , it was possible to write the below code. Trying to understand what actually happens under the hood.
1.When I call f() from the constructor of class A I found that it is calling the child class f(). This is an expected behaviour. But , when the parent constructor calls the overloaded f() before initialising the child class members ,why “B” is getting printed.
2.Why I have two values for a final variable X (x=null , x=B)?.
class A{
A(){
System.out.println("A's Constructor");
f();
}
void f() {System.out.println("A");}
}
class B extends A{
B(){
System.out.println("B's Constructor");
f();
}
final String x = "B";
void f() {System.out.println(x);}
}
public class JavaPOCSamples {
public static void main(String[] args) {
// TODO Auto-generated method stub
//System.out.println("Java POC");
new B();
}
}
Output as below when “B”.trim() is used in the above code:
A's Constructor
null // Note that a final variable X is null
B's Constructor
B // Note that a final variable X is changed to "B"
It is exactly the expected behaviour and is exactly why you should never call overridable methods from a constructor.
The constructor of B first calls the constructor of A, that calls f(), (from class B because it's overridden), that prints x, which is still null. Then B sets it's initialized member variables (so x is no longer null), prints something and calls f() again...
That's is because of the Java Language Specification of Inheritance. Here is a quote from Oracle Java docs.
With super(), the superclass no-argument constructor is called. With super(parameter list), the superclass constructor with a matching parameter list is called.
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.
Small & Simple Explanation:
super() means the constructor (equivalent) of immediate parent class.
class A{
A(){
System.out.println("A's Constructor");
f();
}
// overloaded constructor
// calling super(int a) in child class will call this
A(int a){
System.out.println("A's Constructor " + a);
f();
}
void f() {System.out.println("A");}
}
Specs means, in an inheritance, when an object of the Child Class is created/instantiated, the Object of the Parent Class must instantiate first. So by default super() is invoked always even if you don't invoke it explicitly (any of the overloaded super(arg...) method) in your code.
If you call an overloaded super(args...) of your parent class from your child class, then the default super() is not called.
That means, in your code, Java Compiler puts the default line of super() at very first line in the child constructor, when you don't invoke any of super constructors.
Practical Proof ?? (in your code..??)
class A{
A(){
System.out.println("A's Constructor");
f();
}
// overloaded constructor
// calling super(int a) in child class will call this
A(int a){
System.out.println("A's Constructor " + a);
f();
}
void f() {System.out.println("A");}
}
class B extends A{
B(){
// super(); java adds this line when you don't put any super(args...) call
System.out.println("B's Constructor");
f();
}
B(int a){
super(a);
System.out.println("B's Constructor "+ a);
f();
}
final String x = "B".trim();
void f() {System.out.println(x);}
}
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
//System.out.println("Java POC");
new B(5);
}
}
Output: (Read comments for some hints..)
A's Constructor 5
null
B's Constructor 5
B
try to play with super() calls.. and get more questions to learn Java deeper. :)
Cheers!!
Recommended reads...
https://stackoverflow.com/a/3767389/6446770
https://stackoverflow.com/a/3767391/6446770
https://stackoverflow.com/a/3767421/6446770

Constructor of a derived class (Java)

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.

invoking constructor in java

class A {
A() {
System.out.print("A");
}
}
class B extends A {
B() {
System.out.print("B");
}
}
class C extends B {
C() {
System.out.print("C");
}
}
public class My extends C {
My(){
super();
}
public static void main(String[] args) {
My m = new My();
}
}
Question starts from one Interview Question (what happens when an object is created in Java?)
and answer is...
The constructor for the most derived class is invoked. The first
thing a constructor does is call the consctructor for its
superclasses. This process continues until the constrcutor for
java.lang.Object is called, as java.lang.Object is the base class for
all objects in java. Before the body of the constructor is executed,
all instance variable initializers and initialization blocks are
executed. Then the body of the constructor is executed. Thus, the
constructor for the base class completes first and constructor for the
most derived class completes last.
So, according to above statement, answer should be ABCC, but it showing only ABC. Although, when i'm commenting the super() in derived constructor. Then, output is ABC. Please, help me to figure out, did i misunderstand the above paragraph. ?
No, the answer is ABC
My m = new My();
The above first invokes My class, then a super call is made to its super class i.e., C class, then a super call to B class is made, then a super call to A Class, then a Super call to java.lang.Object as all objects extend java.lang.Object.
Thus the answer is ABC.
You don't really need to explicitly call super() in your My class as it'd be included by the compiler unless you call an overloaded constructor of that class like this(something).
The below code will print ABC
To invoke the constructor of the super class, the compiler will implicitly call the super() in each and every class extending the class, if you are not calling the super construcotr explicitly.

Java compiler super() constructor generals [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Use of ‘super’ keyword when accessing non-overridden superclass methods
I'm new to Java and have been reading a lot about it lately to get more knowledge and experience about the language. I have a question about inherited methods and extending classes when the compiler inserts automatic code.
I've been reading that if I create class A with some methods including lets say a method called checkDuePeriod(), and then create a class B which extends class A and its methods.
If I then call the method checkDuePeriod() within class B without using the super.checkDuePeriod() syntax, during compilation will the compiler include the super. before checkDuePeriod() or will the fact that the compiler includes the super() constructor automatically when compiling the class imply the super. call of the methods that class B calls from class A?
I'm a little confused about this. Thanks in advance.
The super class's implementation of regular methods is not automatically invoked in sub classes, but a form of the super class's constructor must be called in a sub class's constructor.
In some cases, the call to super() is implied, such as when the super class has a default (no-parameter) constructor. However, if no default constructor exists in the super class, the sub class's constructors must invoke a super class constructor directly or indirectly.
Default constructor example:
public class A {
public A() {
// default constructor for A
}
}
public class B extends A {
public B() {
super(); // this call is unnecessary; the compiler will add it implicitly
}
}
Super class without default constructor:
public class A {
public A(int i) {
// only constructor present has a single int parameter
}
}
public class B extends A {
public B() {
// will not compile without direct call to super(int)!
super(100);
}
}
If you call checkDuePeriod() in B without super., means you want to invoke the method that belongs to the this instance (represented by this within B) of B. So, it equivalent to saying this.checkDuePeriod(), so it just doesn't make sense for the compiler to add super. in the front.
super. is something that you must explicitly add to tell the compiler that you want to call the A's version of the method (it is required specially in case B has overridden the implementation provided by A for the method).
Call of super() as a default constructor (constructor with no args) can be direct or non direct but it garants that fields of extendable class are properly initialized.
for example:
public class A {
StringBuilder sb;
public A() {
sb = new StringBuilder();
}
}
public class B extends A {
public B() {
//the default constructor is called automatically
}
public void someMethod(){
//sb was not initialized in B class,
//but we can use it, because java garants that it was initialized
//and has non null value
sb.toString();
}
}
But in case of methods:
Methods implement some logic. And if we need to rewrite logic of super class we use
public class B extends A {
public B() {
}
public boolean checkDuePeriod(){
//new check goes here
}
}
and if we want just implement some extra check, using the value returned from checkDuePeriod() of superclass we should do something like this
public class B extends A {
public B() {
}
public boolean checkDuePeriod(){
if(super.checkDuePeriod()){
//extra check goes here
}else{
//do something else if need
}
return checkResult;
}
}
First about the Constructors:
- When ever an object of a class is created, its constructor is initialized and at that time immediately the constructor of its super-class is called till the Object class,
- In this process all the instance variables are declared and initialized.
- Consider this scenario.
Dog is a sub-class of Canine and Canine is a sub-class of Animal
Now when Dog object is initialized, before the object actually forms, the Canine class object must be form, and before Canine object can form the Animal class object is to be formed, and before that Object class object must be form,
So the sequence of object formed is:
Object ---> Animal ---> Canine ---> Dog
So the Constructor of the Super-Class is Called before the Sub-Class.
Now with the Method:
The most specific version of the method that class is called.
Eg:
public class A{
public void go(){
}
}
class B extends A{
public static void main(String[] args){
new B().go(); // As B has not overridden the go() method of its super class,
// so the super-class implementation of the go() will be working here
}
}

using constructor from the super class

Java does not allow multiple inheritance, meaning that a class cannot inherit from two classes, which does not have anything in common, meaning that they are not on the same inheritance path. However, a class can inherit from more classes, if these classes are super classes of the direct super class of the class. But the class inherits from these classes indirectly, meaning that it does not "see" anything from these upper super classes, right? I was confused when considering constructors (using super() in the constructor). For example, if we have the following classes:
public class A {
public A() {
....
}
}
public class B extends A {
public B() {
super();
....
}
}
public class C extends B {
public C() {
super();
....
}
}
the constructor of class C invokes first the constructor of class B using super(). When this happens, the constructor of B itself invokes first the constructor of A (with super()), but the constructor of C does not know anything about the constructor of A, right? I mean, the inheritance is only from the direct super class - the first (nearest) class from the inheritance hierarchy. This is my question - with super() we mean only the constructor of the direct super class, no matter how many other classes we have in the inheritance hierarchy.
And this does not apply only for constructors, but for any methods and instance variables..
Regards
You have to invoke some constructor in your immediate base class. This can be
public class A {
public A() {
....
}
public A(String foo) {
....
}
}
public class B extends A {
public B() {
super();
.. or ..
super("ThisIsAB")
}
}
public class C extends B {
public C() {
super();
....
}
}
So for constructors you cannot AVOID constructing your intermediate base classes, but you can choose which constructor to use. If there is only the no-args constructor it's all handled for you with an implicit call to super. With multiple constructors you have some more choices.
super can refer to any non-private variable or method in any base class. So methods and variables are not the same as constructors in this respect.
Even if you could avoid calling the intermediate ctor, you wouldn't want to, because that would mean you had uninitialized pieces of the intermediate classes that might be acessed by the bottom-most derived class. To horrible effects.
But I sense that you're trying to trick your way around Java to do multiple inheritance. That is a Bad Thing. Instead, you can do it Java-wise by using an interface
class B extends A implements C {
// ... implement C methods here
}
or by using aggregation
class B extends A {
private C c;
}
Constructors for all parents are called. In fact, deep down C knows about A because B extends A. For example, if the class A contained method foo(), then you could call foo() from C.
So from your example, C calls the constructor from B, which calls the constructor from A. Additionnally, A also extends from the class Object. So the constructor in the class Object is also called!
Furthermore, you do not need to add a call to super(). If there is no call for the constructor of the parent, super is call implicitly.
As you say, C's constructor invokes B's constructor which invokes A's constructor. You can call any "A" methods on a C object, and a C object can see non-private fields in A.
Even if you override A's method "foo" in C, you can get the A version with "super.foo()", assuming B doesn't also override it.
As far as C knows, anything that it does not overwritten in C is contained in B, even if under the covers class A is where the implementation might be.
public class A {
public A() {
}
public void aMethod() {
}
}
public class B extends A {
public B() {
super();
}
}
public class C extends B {
public C() {
super();
}
public void doWork() {
super.aMethod();
}
}
So in this case A handles the implementation of aMethod(), even though calling super() in C's constructor called B's constructor directly, not A's.

Categories

Resources