Inheritance and recursion Inheritance and recursion java java

Inheritance and recursion


This is expected. This is what happens for an instance of B.

class A {    void recursive(int i) { // <-- 3. this gets called        System.out.println("A.recursive(" + i + ")");        if (i > 0) {            recursive(i - 1); // <-- 4. this calls the overriden "recursive" method in class B, going back to 1.        }    }}class B extends A {    void recursive(int i) { // <-- 1. this gets called        System.out.println("B.recursive(" + i + ")");        super.recursive(i + 1); // <-- 2. this calls the "recursive" method of the parent class    }}

As such, the calls are alternating between A and B.

This doesn't happen in the case of an instance of A because the overriden method won't be called.


Because recursive(i - 1); in A refers to this.recursive(i - 1); which is B#recursive in second case. So, super and this will be called in recursive function alternatively.

void recursive(int i) {    System.out.println("B.recursive(" + i + ")");    super.recursive(i + 1);//Method of A will be called}

in A

void recursive(int i) {    System.out.println("A.recursive(" + i + ")");    if (i > 0) {        this.recursive(i - 1);// call B#recursive    }}


The other answers have all explained the essential point, that once an instance method is overridden it stays overridden and there's no getting it back except through super. B.recursive() invokes A.recursive(). A.recursive() then invokes recursive(), which resolves to the override in B. And we ping pong back and forth until the end of the universe or a StackOverflowError, whichever comes first.

It would be nice if one could write this.recursive(i-1) in A to get its own implementation, but that would probably break things and have other unfortunate consequences, so this.recursive(i-1) in A invokes B.recursive() and so forth.

There is a way to get the expected behavior, but it requires foresight. In other words, you must know in advance that you want a super.recursive() in a subtype of A to get trapped, so to speak, in the A implementation. It is done like so:

class A {    void recursive(int i) {        doRecursive(i);    }    private void doRecursive(int i) {        System.out.println("A.recursive(" + i + ")");        if (i > 0) {            doRecursive(i - 1);        }    }}class B extends A {    void recursive(int i) {        System.out.println("B.recursive(" + i + ")");        super.recursive(i + 1);    }}

Since A.recursive() invokes doRecursive() and doRecursive() can never be overridden, A is assured that it is calling its own logic.