views:

1691

answers:

5

Hello,

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

+2  A: 

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.

Paul Tomblin
+4  A: 

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.

krosenvold
I've never done it, but I thought that if you don't start your ctor with a "super" call, it will call the default (no argument) constructor for you.
Paul Tomblin
Yes, I edited slightly.
krosenvold
+3  A: 

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.

Thierry-Dimitri Roy
+1  A: 

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.

Ryan Ahearn
+2  A: 

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;
}
Charlie Martin
multiple inheritance isnt necessarily a bad thing - just not supported in java. In languages that does it allows nice things like mixins - where you extend classes to add in functionality to your own, with no work. eg in ruby mixins http://www.juixe.com/techknow/index.php/2006/06/15/mixins-in-ruby/
Chii