views:

1016

answers:

10

Hallo,

I have a question about inheritance in Java.

I have two classes A and B, and class B, inherits from A:

public class A {
     public A() {
         System.out.println("Hi!");
     }
}


public class B extends A {
     public B() {
         System.out.println("Bye!");
     }

     public static void main(String[] args) {
         B b = new B();
     }
}

When I run program B, the output is:

Hi! Bye!

My question is: why the constructor of class A is invoked, when I create and object of class B ? I know that B inherits everything from A - all instance or class variables, and all methods, and in this sense an object of B has all characteristics of A plus some other characteristics defined in B. However, I didn't know and didn't imagine that when I create an object of type B, the constructor of A is also invoked. So, writing this:

B b = new B();

creates two objects - one of type B, and one of type A.

This is very interesting, but can somebody explain why exactly this happens?

Thank you very much in advance.

+3  A: 

Remember inheritance is an "is a" relationship between the base class and the subclass, thus every time you have an instance of a subclass, by definition you will also have an instance of the base class (as part of the instance, not as two separate instances). To initialize the base class properly the constructor is called.

Additionally, think about what would happen if you subclass depended on some internal state of the base class. Wouldn't you want the instance of the base class to be initialized then?

Brian Rasmussen
+7  A: 

It doesn't create 2 objects, it only creates one instance of B. The reason the super class constructor is invoked is because, like you said, B has all of the fields of A, and these fields need to be initialized.

Outlaw Programmer
It isn't 2 objects. If you were to say it in words, "B is an A".A car is an automobile. It isn't 2 objects.
John Gardner
Class A needs a chance to initialize itself.
Steve Kuo
+9  A: 

It doesn't create two objects, only one: B.

When inheriting from another class, you must call super() in your constructor. If you don't, the compiler will insert that call for you as you can plainly see.

The superclass constructors are called because otherwise the object would be left in an uninitialized state, possibly unbeknownst to the developer of the subclass.

Edit (Software Monkey): Your subclass actually looks like this after the compiler inserts the super call:

public class B extends A {
    public B() {
        super();
        System.out.println("Bye!");
        }
    ...
    }
Kevin
I think the fundamental misunderstanding here is whether or not the call to super() is creating a new object. It isn't.
Outlaw Programmer
+1  A: 

If A intializes members in it's constructor and you forget to call super in your derived class then the members of A could be in a bad state. Java is trying to stop you from shooting yourself in the foot.

basszero
+1  A: 

The constructor contains all of the initialization for A. You are not creating two objects. You are creating one object, then running the initializer for the superclass to initialize its members, and then running the initializer for the deriving class to initialize its members.

Eddie
+2  A: 

It does not create two objects, it just creates one object b. b is of type B and of type A. A constructor is basically saying here is what you need to do to construct me. So when you are creating a new "B" instance, you are building an object that is both a B() and an A(). Imagine the following scenario:

class Q {
  int i;
  public Q() {
    // set default value
    i= 99;
  }
}

class Z extends Q {
  public Z() {
  }
}

If the constructor for Q WAS NOT called, how would i get its default value?

Rob Di Marco
+1  A: 

Only one object is created, both contractors are running on the same object.

The reason is simple, as you know B has all the variables and methods of A, so if some variable of A needs initializing so methods of A can work someone has to initialize it - and that someone is A's constructor.

for example:

public class A {
     public A() {
        x = 1;
     }
     private int x;
     public int getX() {
        return x;
     }
}


public class B extends A {
     public B() {
     }

     public static void main(String[] args) {
         B b = new B();
         System.out.println(b.getX()); // should print 1 
     }
}
Nir
+2  A: 

This is done because the constructor is used to initialize the object. Since B is also an A, it calls the constructor for A first, then the constructor for B.

As a side note, you can use super(arg1, etc) to choose which constructor of A is called based on the parameter types you pass... but it must be the first line in the constructor.

R. Bemrose
+1  A: 

The creation of B does not create an extra A.

But by creating B, you create a kind of A, because B is a A.

Java/C++ call the constructor of A for your implicitly. Why? Language design. But doing so is fine, because the constructor of A might contain some initializations. And as B uses all the features and bugs of A, these features better be initialized properly.

Leonidas
+1  A: 

The constructor of a class is very important concept in most OOP

Classes, by providing state and the means to manipulate that state, allow the easier maintenance of invariants. The constructors role is to get the class into a state that conforms to those invariants (or throws thus forbidding usage of an invliad object). this is somewhat looser than intended in many languages since the constructor is allowed to pass its own 'this' reference elsewhere but this is at least under the control of the class (as such it can know that it is in a sufficiently stable and valid state for it to be accessible to the rest of the world)

Inheritance makes this complex since B is-a A in a very real sense and thus can invoke any of the methods provided by A. The parts of B that are A should therefore get their chance to initialize themselves before B gets a look in, thus the constructor for A is called before the real work of the B constructor begins.

ShuggyCoUk