1

How to call Super::printThree from Super::Super()?
In the example below I call Test::printThree instead.

class Super {
        Super() { 
        printThree(); // I want Super::printThree here!
        }
        void printThree() { System.out.println("three"); }
}
class Test extends Super {
        int three = 3
        public static void main(String[] args) {
                Test t = new Test();
                t.printThree();
        }
        void printThree() { System.out.println(three); }
}

output:
0    //Test::printThree from Super::Super()
3    //Test::printThree from t.printThree()
all
  • 314
  • 5
  • 16

3 Answers3

11

You can't - it's a method which has been overridden in the subclass; you can't force a non-virtual method call. If you want to call a method non-virtually, either make the method private or final.

In general it's a bad idea to call a non-final method within a constructor for precisely this reason - the subclass constructor body won't have been executed yet, so you're effectively calling a method in an environment which hasn't been fully initialized.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I know this answer was posted long back but why does `printThree` of the Subclass get called even when it is invoked by the constructor of the Supercalss? Is it only because the reference variable of the object is of type Subclass? Is there detailed documentation on how this works? I only found a short sentence(2nd paragraph from the end) mentioned here https://dev.java/learn/inheritance/polymorphism/. I'm fairly new to Java. Thanks. – Elben Aug 31 '23 at 04:25
  • 1
    @Elben: Even during a constructor call, the object type is "whatever the final type will be" (so `Test` in this case). It doesn't change type during construction. – Jon Skeet Aug 31 '23 at 06:15
1

You're violating the whole idea behind dynamic dispatching and inheritance here. Just don't do it (and it's pretty hard to circumvent in java anyhow). Instead make the function private and/or final so that it can't be overwritten in the inherited class

Voo
  • 29,040
  • 11
  • 82
  • 156
1

If Super needs to ensure that printThree() isn't overridden, that method needs to be declared as final. Alternatively, the overriding method in Test can decide to call the overriden method if it chooses:

@Override
void printThree() { super.printThree(); }

If the base class doesn't mark a method as final, it's giving up the right not to have deriving classes override it and do as they please.

Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
  • Except that he doesn't want to call the super method in the inherited class but the other way round. So the idea with `super` obviously won't work, because the super for his Super class is Object. – Voo Aug 28 '11 at 19:50
  • @Voo - agreed, I'm just pointing out the possible scenarios. What he wants isn't possible. – Paul Bellora Aug 28 '11 at 19:51