Using a constructor from a superclass

Java does not allow multiple inheritance, which means that a class cannot inherit from two classes that have nothing in common, which means that they are not on the same inheritance path. However, a class can inherit more classes if those classes are superclasses of the direct superclass of the class. But the class inherits from these classes indirectly, which means it doesn't "see" any of these top superclasses, does it? I was confused when considering constructors (using super () in a 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 first calls the constructor of class B using super (). When this happens, B's constructor itself calls A's constructor first (with super ()), but C's constructor doesn't know anything about A's constructor, right? I mean, inheritance only comes from the direct superclass - the first (closest) class from the inheritance hierarchy. This is my question - with super () we only mean the direct superclass constructor, no matter how many other classes we have in the inheritance hierarchy. And this does not only apply to constructors, but to any methods and instance variables ..

Hello

+1


source to share


5 answers


You have to call some constructor in your base class. It could 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 can't AVOID to create intermediate base classes, but you can choose which constructor to use. If there is only a no-args constructor, this is all handled for you with an implicit call to super. With multiple constructors, you have a few more options.

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.

+4


source


Even if you could avoid calling the intermediate ctor, you wouldn't want that, because that would mean you had uninitialized parts of the intermediate classes that could be used by the lowest derived class. To dire consequences.

But I feel like you are trying to cheat your way around Java to do multiple inheritance. This is a bad thing. Instead, you can do it in different ways using the interface

class B extends A implements C {
    // ... implement C methods here
}

      



or using aggregation

class B extends A {
    private C c;
}

      

+4


source


Constructors for all parents are called. In fact, deep in C is aware of A because B extends A. For example, if class A contains a method foo (), you can call foo () from C.

So, from your example, C calls the constructor from B, which calls the constructor from A. Enough, A is also propagated from the Object class. Therefore, the constructor of the Object class is also called!

Also, you don't need to add a super () call. If there is no parent's constructor call, super is implicit.

+3


source


As you say, C's constructor calls B's constructor, which calls A.'s constructor. You can call any "A" methods on C, and C can see non-private fields in A.

Even if you override the "foo" method in C, you can get the version of A with "super.foo ()", assuming B does not override it either.

+2


source


As far as C knows, anything that is not overwritten in C is contained in B, even if there is an implementation under the wrappers of class A.

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 the call to super () in C's constructor is called B's constructor directly, not A.

+1


source







All Articles