0

I know that you can use super.super.methodName() to invoke the grandparent's version of a method, but is there any way to directly invoke the grandparent class's constructor in a chained constructor call?

(Simplified) Example:

 class A {
    public A(){}
    public A(int i, boolean b) {
        /*...*/
    }
}

class B extends A {
    public B(){}
    public B(int i) {
        super(i, true);
    }

}

class C extends B {
    public C(int i)
        {
        super.super(i,false);  //This is not allowed, but you 
            //can see what I'm trying to do (call A(i,false).) 
            //this=new A(i,false); also doesn't work b/c this can't be LHS
            //of assignment
        }
}

..or is this disallowed, and did I just demonstrate the reasoning for doing so in attempting to make a super.superclass(grandparent) constructor call not possible in the (parent)superclass?

Mer
  • 762
  • 1
  • 6
  • 12
  • 2
    If you want to do that, then you should reconsider your design. – stealthjong Aug 28 '14 at 08:10
  • 5
    _I know that you can use super.super.methodName() to invoke the grandparent's version of a method_ ... ***What?*** – BackSlash Aug 28 '14 at 08:11
  • 2
    "I know that you can use `super.super.methodName()`"... no you can't. – Mena Aug 28 '14 at 08:11
  • Related (if not a duplicate): http://stackoverflow.com/questions/586363/why-is-super-super-method-not-allowed-in-java – JonK Aug 28 '14 at 08:14
  • If you were able to call `super.super(i,false);`, how do you expect the _B part_ of you class to construct itself ? And no, you can't call `super()` later, since it will call the empty constructor of A, so you would call two constructors of A in the end. – Volune Aug 28 '14 at 08:16

2 Answers2

8

No, and this is by design. The intermediate class intentionally hides some of the functionality of its superclass, and the constructor is one area where it does so.

Think about it like this. Suppose you have three classes: Animal, Dog, Terrier.

Dog extends Animal

Terrier extends Dog

In your Terrier constructor, it's quite appropriate for it to call the Dog constructor. What you're doing is to say that when a Terrier is created it should do its doggy-related thing, and then afterwards do anything terrier-specific.

But what you're wanting to do is to get the Terrier constructor to invoke the Animal constructor. This is essentially to say that the Terrier should set itself up without regard for the fact that it's a dog. Anything might now happen: the code to initialize the fields needed for the .woof() method won't get dealt with, for instance. Now your Terrier is in a terrible mess when it tries to woof later.

If you're wanting your Terrier to do some Animal setup but avoid the Dog setup, that suggests that your class hierarchy is all wrong: your Terrier probably isn't a Dog at all.

chiastic-security
  • 20,430
  • 4
  • 39
  • 67
0

No. But you can get around it.

You can call super.foo(), then in your parent foo method, you call super.foo()

For instance

class A {

  public void foo() {
    System.out.println("I want this");
  }
}

class B extends A {
  public void foo() {
    super.foo();
  }
}

class C extends B {
   @Test
   public void callFooTest() {
       C c = new C(); 
       c.foo();
       //call foo() and you will get the one from Class A
   }
}

The same works for constructors

Shervin Asgari
  • 23,901
  • 30
  • 103
  • 143