Java Constructor weird behaviour - java

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.

Related

What does "extends" actually do?

I am currently studying the concept of "class abstraction" and "extension" and have been wondering:
"If I declare a parametrized constructor inside my abstract class why won't extension on another class work unless I declare myself the constructor with the super keyword invoking the parameters of the abstract class's constructor?"
I understand the fact that extension instances the previous abstract class into the extended one and tries to call the default constructor but have been wondering why it gives out an error.
Is it because the constructor has been parametrized or simply because the empty constructor does not exist?
Does the extends keyword call something along the lines of this?
Object myClass = new AbstractClass();
And the missing parameters are the reason why it gives out an error so something along the lines of this would be correct
Object myClass = new AbstractClass(int foo,float boo);
And if that is it, does the super keyword essentially, if you'll allow me the term, "put" the parameters given in the parenthesis "inside" the constructor?
If that's not it what am I getting wrong? How does it actually work?
You should think of the extends keyword, in this context, as just saying that a class is the subclass of another class, and does nothing else. And that there are rules governing how subclasses and superclasses should work.
When you construct a subclass, you must construct its superclass first. For example, to create a Bird, you must first create an Animal. That makes sense doesn't it? To demonstrate this in code:
class Animal {
public Animal() {
System.out.println("Animal");
}
}
class Bird extends Animal {
public Bird() {
System.out.println("Bird");
}
}
Doing new Bird() will first print Animal and then Bird, because the Animal's constructor is called first, and then the Bird constructor. So actually, the Bird constructor implicitly calls the superclass' constructor. This can be written as:
public Bird() {
super();
System.out.println("Bird");
}
Now what happens if the super class does not have a parameterless constructor? Let's say the constructor of Animal now takes a String name as argument. You still need to call the superclass' constructor first, but super() won't work because super() needs a string parameter!
Therefore, the compiler gives you an error. This can be fixed by calling super() explicit with a parameter.
"If I declare a parametrized constructor inside my abstract class why
won't extension on another class work unless I declare myself the
constructor with the super keyword invoking the parameters of the
abstract class's constructor?"
Because the super class says that it MUST be constructor using that declared constructor and there is no other way around. This applies to every extending class - required constructor must be called.
The same happens with any class when you declare other constructor than default one. For example, having
public class A{
//no default no-arg ctor here
public A(String name){
....
}
}
public class B{
//default no-arg ctor will be created
}
so then
B b=new B();
A a=new A(); //// INVALID!
A a=new A("foobar"); // yeah that is it
The same applies when you are extending classes. To construct child instance, you must first "internally create parent instance" calling super.constructor. Since there is no default constructor, ANY of explicit declared superconstructors must be used.
When initializing an Object the constructor will always be called. Even if you do not define one constructor there will be a default one without any parameters. So if you define a constructor in the abstract class, you have to call that constructor with super().
If you do not define any constructors, then it will be implicitly called as the default one.
If I declare a parametrized constructor inside my abstract class why won't extension on another class work unless I declare myself the constructor with the super keyword invoking the parameters of the abstract class's constructor?
There is no default constructor available in AbstractClass since you define a parametrised constructor. If you don't define a constructor yourself, a default constructor without arguments is implicitly created. You can manually add such one now or you need to use the only available constructor (which is parametrised) with super().
Example of your code with defining constructor without arguments:
class AbstractClass {
AbstractClass() {} // added manually since not created implicitly
AbstractClass(int foo, float boo) {}
}
class RealClass extends AbstractClass {
RealClass() { } // calls super() implicitly
}
AbstractClass myClass = new RealClass();
Example of your code with calling super() with arguments:
class RealClass extends AbstractClass {
RealClass() {
super(1, 2);
}
}
class AbstractClass {
AbstractClass(int foo, float boo) {}
}
AbstractClass myClass = new RealClass();

why their should override super class parameterize constructor in sub class constructor when it extends from super class?

why the code super(0) is needed in sub class constructor to compile when creating a sub class constrctor?
public class Super {
public Super(int i) {
System.out.println("super(int i)");
}
}
class Sub extends Super{
public Sub(int i) {
super(0); // why this code needed here to compile?
System.out.println("Sub(int)");
}
}
class Demo{
public static void main(String[] args) {
Sub s1=new Sub(100);
}
}
Super class should be constructed before constructing sub class.
Since the super class does not have a default constructor, so you have to call super(0); first.
You can add a default construtor in super class:
public Super(){}
then you do not need call super(0); in sub class.
When Sub class extends Super class, all the members(methods and variables only,constructor not a member) in super class extends to Sub class.
From main method in class Demo called the Sub class Sub(int) constructor,
Then first statement in the Sub(int) constructor have super() call in Super class.It is automatically put java compiler.
But above code haven't default constructor (because you write whatever constructor java compiler don't give default constructor automatically.you need no parameter constructor(default constructor) you have to write it manually) So you need to write super(int) called manually. Because you wrote this constructor in Super class.
If not it is compile error.
Then output as following :
super(int i)
Sub(int)
Instead of above all class in one package you have to Demo class is public(Except Super class). Because It has main method.
That's because in java every subclass need to call constructer of its super class. If you have a default constructer in super class than you don't need to call that explicitly as java does that for you but if you don't have any default constructor in superclass with no parameters but instead you have some constructer(s) with parameter(s) you need to call that in first line of your sub class constructor.

Do i need super when creating a subclass or not?

In this program there is no need for a super to reach the superclass's constructor:
class Base{
Base(){
System.out.println("Base");
}
}
public class test2 extends Base{
test2() {
//super();
System.out.print("test2");
}
public static void main(String argv[]){
test2 c = new test2();
}
}
But this program needs super and gives an error at quest1 constructor saying
constructor quest can't be applied to given types: required int, found no arguments
class Quest {
Quest(int y){
System.out.print("A:"+y);
}
}
class Quest1 extends Quest {
Quest1(int x){
//super(x+1);
System.out.print("B:"+x);
}
}
class Test {
public static void main(String argv[]){
Quest1 q = new Quest1(5);
}
}
JLS 8.8.7. Constructor Body
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.
In
class Base {
Base() {
}
}
public class test2 extends Base {
test2() {
//super();
System.out.print("test2");
}
}
The commented out line is added automatically and since the superclass's no-argument constructor is defined, there is no error.
In the case of
class Quest {
Quest(int y) {
System.out.print("A:"+y);
}
}
class Quest1 extends Quest {
Quest1(int x) {
//super(x+1);
System.out.print("B:"+x);
}
}
The implicit call super() is trying to invoke an undefined constructor in the superclass, which causes the error
Implicit super constructor Quest() is undefined. Must explicitly invoke another constructor.
Uncommenting your explicit constructor call replaces the implicit call and thus the problem is resolved. Alternatively, define a no-argument constructor in the superclass.
You need a call to super() if and only if there's no default constructor (accepting no arguments) for your parent class.
In all other cases (where a constructor with zero arguments exists) you don#t have to code it. It's implicitly called anyway.
These Rules apply:
if your parent class has no constructor at all, it has the default constructor, which takes no arguments -> no need for super();
you parent class declares a constructor with no arguments -> no need for super()
your class has a constructor with arguments but no constructor without arguments -> you need to call one of the defined constructors with mathching arguments via super()
If you create a constructor in super class the you should call the super class constructor (Ex : super()) before the sub class constructor gets call.

Understanding the concept of super?

I'm having trouble wrapping my head around the concept of super(). Java Tutorials gives this example:
public class Superclass {
public void printMethod() {
System.out.println("Printed in Superclass.");
}
}
public class Subclass extends Superclass {
// overrides printMethod in Superclass
public void printMethod() {
super.printMethod();
System.out.println("Printed in Subclass");
}
public static void main(String[] args) {
Subclass s = new Subclass();
s.printMethod();
}
}
But if I am overriding the printMethod, why do I need to invoke the Superclass method? Why can't I just write whatever in the Subclass method of printMethod() and just move on?
There is absolutely no need to call the super.
It just helps you to call the logic contained within super class method if you require that.
Many times you want the exact logic to run and then provide your additional logic.
Overriding always does not mean providing brand new logic. Sometimes you want to provide a slight variation. For e.g., if the method returns a value, then you call the super class method and get the value. Then you make some slight modification in that object using logic in the sub class method and return it back to caller.
You can override it. In that case, the parent method is ignored. super() is used if you want the parent method to be executed in the subclass.
This is used to avoid duplicated code. Let's say you have a class:
public class SuperClass() {
private int var1;
private int var2;
private int var3;
public SuperClass() {
var1 = 1;
var2 = 2;
var3 = 3;
}
}
and a subclass:
public class SubClass() {
private int var1;
private int var2;
private int var3;
private int var4;
public SubClass() {
super();
var4 = 4;
}
}
In this example, you are using super() to invoke superclass constructor (constructor are usually used to initialize members) so you can focus on the SubClass members, and you don't have to repeat all the initialization lines (for var1, var2 and var3).
Basically the super class is the upper most level of the program. When you create a new subclass you must "inherit" from the super class using the keyword 'extends'. This does 2 things; It allows you to use any methods created in the super class, in the subclass and it also allows you overwrite methods in the super class. Basically, if you have one method you want to use in a bunch of classes you use the super class to create it and then the sub-classes can just call the method using standard dot notation.
If you just run this program, Inside PrintMethod of the subclass will call to super class "printMethod" (print "Printed in Superclass") and then execute the things you have written in the sub class method(print "Printed in Subclass").
public void printMethod() {
//super.printMethod(); // comment this line
System.out.println("Printed in Subclass");
}
if you run like this, it will print only the things that you have written in the sub class method.
Idea is, If you want use Super class method information in the sub class, then you can call like Super.MethodName().
Clear Explanation :
public static void main(String[] args) {
Subclass s = new Subclass();
s.printMethod();
}
Subclass s = new Subclass();
(i) when we are creating sub class object what wiill happens?
constructor of subclss will be executed
(ii) Do we have any costructor in sub class (Subclass )
if we have dat will execute..
but we are not having so default costructor will excecute
(iii) what default costructor will have?
Subclass (){
super();
}
(iv) what super() will do?
it calls super class contructor
in super class also we are not having constructor so
will execute default constructor
Superclass(){
super();
}
super class of superclass is Object class
so Object class is the super class of evry class in java
so it will creates object of object class..
object of Object class created
|
and comes to its subclass constructor...//step (iv)
Superclass(){
super(); // executed
}
object of Object class created
|
object of Superclass craeted
so super class constuctror execution also completed so
it will creates Object of SuperClass..
then control comes to its subclass conctructor // step (iii)
so Subclass (){
super(); // executed
}
after completion of subclass constructor it creates the object of subclass
*Important point : after completion of constructor execution
Object of thet class will be created*
object of Object class created
|
object of Superclass craeted
|
object of Subclass craeted
all this happened because of Subclass s = new Subclass();
so when you created object of sub class 3 objects are created..
s.printMethod();
now you are calling a method on subclass object
^
printMethod() is there in super class and sub class
when u r calling a method on sub class object what happens?
(i) it will search for that method in outer most objest: Object of Object class
so now printMethod() is not there in object of object class
(ii) Next its searches in next superclass object ie. object of Superclass
object Superclass object having printMethod() method
(iii) so method found...eventhougth method found controll serches in next sub most object is object of subclass object....
(iv) two methos found in two object but it excecutes sub most object method.
so sub most object is Subclass object...
so it executes the subclass printMethod() method.
Note: when we call a method on object it will executes the sub most objects method if ovverriden.....
now our method is....
public void printMethod() {
super.printMethod();
System.out.println("Printed in Subclass");
}
first line in this method is super.printMethod();
by default super ponts to super class object : object of Superclass
object of Superclass .printMethod() is
public void printMethod() {
System.out.println("Printed in Superclass.");
}
so prints :
Printed in Superclass.
next line is : System.out.println("Printed in Subclass");
so it prints : Printed in Subclass
Note : first while creating object it called super class constructor..
now in method called super class method..
Note:
1.if class not having any constructor jvm assigns default constructor as
ClassName(){
super(); calls super class constructor
}
if class alrdy having constructor
the first line of the constructor should be the super() call.
for example: class A{
int variablea;
A(int a){
variablea=a;
}
public static void main(String[] args) {
A a=new A(2);
}
}
in this example
A(int a){
variablea=a;
} code replaces with
A(int a){
super(); by jvm by default
variablea=a;
}
You can use super in a subclass to refer to its immediate superclass. Super has two general forms.
to call the super class's constructor from the subclass
to access a member of the superclass from the subclass
I'm assuming that you are trying to understand the second one.
An example which might make you understand how super helps in referencing members of the super class:
public class Human {
String name;
int age;
public void printDetails() {
System.out.println("Name:"+name);
System.out.println("Age:"+age);
}
}
public class Student extends Human {
int rollNumber;
String grade;
public void printDetails() {
super.printDetails();
System.out.println("Roll Number:"+rollNumber);
System.out.println("Grade:"+grade);
}
public void printNameAgeAndSayGoodMorning(){
super.printDetails();
System.out.println("Good morning!");
}
public static void main(String[] args) {
Student s = new Student();
s.name="MyName";
s.age=27;
s.rollNumber=3;
s.grade="A+";
s.printDetails();
System.out.println(); //just an empty line
s.printNameAgeAndSayGoodMorning();
}
}
I avoided constructors or any getter/setter methods for simplicity.
In this example, do you think you really have to "just write whatever in the Subclass" instead of reusing the printDetails() method available in the super class?

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
}
}

Categories

Resources