Java: recursion within main-class calls subclass-method instead of its own method
Asked Answered
P

2

7

Example:

class MainClass {
    public doIt() {
        ...
        else doIt();
    }
}

class SubClass extends MainClass {
    @Override
    public doIt() {
        super.doIt();
        ...
    }
}

Now the problem is:

  • I call SubClass.doIt()
  • MainClass.doIt() is called
  • MainClass.doIt() makes recursion calling doIt()
    But: the SubClass.doIt() is called instead of MainClass.doIt()

That is very strange behaviour and problems are programmed! I tried to call the recursion with this.doIt() but that didn't help. Someone has an idea?

Thanks alot for your answers, this problem is solved.

Pedal answered 19/2, 2015 at 18:58 Comment(3)
That's polymorphism for you.Referendum
"That is very strange behaviour" not really, else doIt() is same as else this.doIt() but this refers to current instance, and thanks to dynamic-binding (polymorphism mechanism) code from method of class closest to current type of this is called. Since closest class to SubClass containing doIt is SubClass itself this code is invoked.Osteotome
That's the supposed behavior.Menorrhagia
M
7

That's the supposed behavior, by not setting a method final, that means it can be overriden, so you must always take into account someone can do this. Call's to that method are never guaranteed to be to the method at that level.

You can however solve this problem elegantly, by using a (protected) final method:

class MainClass {

    protected final void innerDoIt () { //final: so no @Override
        ...
        else innerDoIt();
    }

    public void doIt() {
        innerDoIt();
    }

}

And then:

class SubClass extends MainClass {

    @Override
    public doIt() {
        super.doIt();
        ...
    }
}

final ensures, the method can't be overriden. So at that moment, you have a contract (guarantee) that the innerDoIt method is indeed the innerDoIt method you think it is.

So in case you don't wan't the caller to get overriden, simply hedge it into another final method. By making it protected, that method can also be called by the SubClass.

Menorrhagia answered 19/2, 2015 at 19:8 Comment(1)
ok didn't know that, a miracle that all my stuff runs up to now :p - thanks alotPedal
P
1
public class Main {

    public static void main(String[] args) {
        B b = new B();
        b.doIt();
        System.out.println();
        A a = new B();
        a.doIt();
    }


    public static class A{
        boolean check=false;
        public void doIt(){
            System.out.println("A start");
            if(check){

            }
            else{
                check = true;
                doIt();
            }
            System.out.println("A end");
        }
    }
    public static class B extends A{
        @Override
        public void doIt() {
            System.out.println("B start");
            super.doIt();
            System.out.println("B end");
        }
    }
}

In this example, both b and a are instances of class B, so as you probably expect, a.doIt() and b.doIt() will output the same result.

B start
A start
B start
A start
A end
B end
A end
B end

B start
A start
B start
A start
A end
B end
A end
B end

When you call doIt(), you are implicitly calling this.doIt(), and this is an instance of class B. There is no syntax to do what you want do without seperating the content of doIt() (see CommuSoft's answer)

Paradiddle answered 19/2, 2015 at 19:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.