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.
Related
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.
Lets say that we have the following code:
class A {
public void doLogic() {
System.out.println("doLogic from A");
}
}
class B extends A {
#Override
public void doLogic() {
System.out.println("doLogic from B");
}
public void doDifferentLogic() {
System.out.println("doDifferentLogic from B");
super.doLogic();
}
}
class C extends B {
#Override
public void doLogic() {
System.out.println("doLogic from C");
}
}
public class Test {
public static void main(String[] args) {
C c = new C();
c.doDifferentLogic();
}
}
When we execute this code the expected behavior is the following:
Since c holds a reference to object of class C, when you invoke the c.doDifferentLogic() method the JVM searches for the method in the C class and since it is not found it starts looking at the inheritance tree. As expected the doDifferentLogic() method is found in the super class and executed. However the construct super.doLogic() is expected to look from the current reference "Point of View", which is of type C. So the super of C should B, but instead the method from the top class A is invoked.
If you remove the super keyword, or replace it with the this keyword (which is the same as "this" is implicit), you get the expected polymorphic behavior and the doLogic() from C class is invoked.
So my question is:
Should call to super.doLogic() be this.super.doLogic()(2), instead of static.super.doLogic()(1) ?
Both are invalid constructs, they are here just to try to explain myself better.
(1)or in other words - from the reference to the current object c , get the superclass of the current object and invoke the doLogic() method instead of
(2)from this class get the superclass and invoke its doLogic() method ?
In Java, the super keyword always refers to the superclass of the type in which the keyword is used, not the superclass of the dynamic type of the object on which the method is invoked. In other words, super is resolved statically, not dynamically. This means that in the context of class B, the super keyword always refers to class A, regardless of whether the B method is executed using a C object as the receiver. To the best of my knowledge, there isn't a way to dynamically determine the superclass type and use its methods without using reflection.
Hope this helps!
Here is where the JLS defines this specifically:
If the form is super . NonWildTypeArgumentsopt Identifier, then the name of the method is the Identifier and the class to be searched is the superclass of the class whose declaration contains the method invocation.
So Java considers super as referring to the superclass of the class enclosing the super.method call, not the actual run time type.
Whenever the super.doLogic() from classB is executed, it will always refer to the doLogic() method of the super class of classB which in this case would be classA. This is the desired behavior so that control does not keep passing between classes within the same method. This is the concept of a class context. Once you are in the context of a class, you will have to follow the rules established by that class and not keep passing control between different contexts.
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.
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
}
}
I am an AP Java Student and I am practicing for my exam. I came across this question and I don't understand the answer:
Consider the following classes:
public class A
{
public A() { methodOne(); }
public void methodOne() { System.out.print("A"); }
}
public class B extends A
{
public B() { System.out.print("*"); }
public void methodOne() { System.out.print("B"); }
}
What is the output when the following code is executed:
A obj = new B();
The correct answer is B*. Can someone please explain to me the sequence of method calls?
The B constructor is called. The first implicit instruction of the B constructor is super() (call the default constructor of super class). So A's constructor is called. A's constructor calls super(), which invokes the java.lang.Object constructor, which doesn't print anything. Then methodOne() is called. Since the object is of type B, the B's version of methodOne is called, and B is printed. Then the B constructor continues executing, and * is printed.
It must be noted that calling an overridable method from a constructor (like A's constructor does) is very bad practice: it calls a method on an object which is not constructed yet.
The base class must be constructed before the derived class.
First A() is called which calls methodOne() which prints B.
Next, B() is called which prints *.