0

I'm currently taking my first Java class and we've recently gone over the topics of polymorphism and inheritance. I was trying a few things in order to get a better understanding of how things work and I was wondering if someone can help me understand why the following code gives me the output and also the issues that can arise when we combine inheritance and overriding of methods.

public class AClass {
public void m1() {
    System.out.println("A.m1()");
    this.m2();
}
public void m2() {
    System.out.println("A.m2()");
}

public static void main(String [] args) {
AClass A = new AClass();
BClass B = new BClass();

A.m1();
A.m2();
B.m1();

public class BClass extends AClass {

@Override
public void m2() {

    // TODO Auto-generated method stub
    System.out.println("B.m2()");
}

}

The output that I get is:

A.m1()
A.m2()
A.m2()
A.m1()
B.m2()

Also, If I add a super.m1() call in my m2() method for class B, I get a stack overflow error. Can somebody tell me why that happens? Thanks!

3
  • 1
    m2 in BClass calls m1 in AClass, which calls m2, and so on (infinite recursion). Commented Dec 13, 2014 at 2:54
  • Thanks for the reply, if you don't mind could go over it step-by-step, as in I'm unable to understand why we'd have an infinite recursion, why would it continue to run? Commented Dec 13, 2014 at 3:17
  • Debug it and step through the code. Commented Dec 13, 2014 at 3:19

4 Answers 4

1

Also, If I add a super.m1() call in my m2() method for class B, I get a stack overflow error. Can somebody tell me why that happens?

Function calls are stacked over one another in memory. In your code,

public class AClass {
public void m1() {
    System.out.println("A.m1()");
    this.m2();
}
public void m2() {
    System.out.println("A.m2()");
}

public static void main(String [] args) {
    AClass A = new AClass();
    BClass B = new BClass();

    B.m1();
}

public class BClass extends AClass {

@Override
public void m2() {

    // TODO Auto-generated method stub
    System.out.println("B.m2()");
    super.m1();
}

}

Your code leads to a never ending sequence

  1. main is in the bottom of the stack.
  2. the statement B.m1() in main calls m1() which is pushed into the stack over main.
  3. the statement this.m2() in the body of m1() calls the overridden m2() which is pushed into the stack over m1().
  4. the statement super.m1() in the body of overridden m2() calls m1() which is pushed into the stack over m2().
  5. Go back to step 3

Function calls are pushed into the stack one over the other, and none is popped out. This leads to stack overflow.

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

1

The infinite recursion can be explained in the following way:

The infinite recursion is caused by the call B.m1(). Class BClass extends AClass,so BClass inherits both the public methods of AClass i.e. methods m1 and m2. So the method call B.m1() calls the method m1 of BClass which it inherits from classA. Inside m1() the call this.m2() is actually equivalent to B.m2().Thus it calls the overridden method m2() from BClass because the overridden method has more priority than the method originally implemented in the super class.But when m2 in BClass is called, it in turn calls method m1() of AClass again via super.m1() and it in turn again calls overridden method of BClass via this.m2().This causes infinite recursion.

Comments

0

Your case is quite simple. When you override methods of parent classes, you replace its implementation by @Override method in child class. For example, when you call B.m1(), java watches for m1 method in Bclass and uses method with the same signature from Aclass if didn't find some. Then it watches for m2() method in Bclass, finds some and calls it.

Polymorphism is more complex. It allows to call same methods from child classes without knowledge about these exact classes. I've overwritten some code from related wikipedia page:

abstract class Animal {
    abstract String talk();
}

class Cat extends Animal {
    @Override
    String talk() {
        return "Meow!";
    }
}

class Dog extends Animal {
    @Override
    String talk() {
        return "Woof!";
    }
}

void main() {
    Animal[] animals = new Animal[size];
    //then goes creation
    for (Animal a : animals) {
        a.talk();
    }
}

3 Comments

Thanks! That makes sense however I'm still not completely sure as to why the program crashes, I don't see why we get into an infinite loop of sorts (when I add the super.m1() method)
When you add super.m1() to the beginning of B.m2() method, the code goes that way: B.m1() -> A.m1() -> B.m1() -> A.m1() again and again.
In more detail: When you call B.m1(), the code in A.m1() will be executed because although class B extends class A, it doesn't overwrite m1. The problem is that A.m1() calls m2() (after printing "A.m1()") which has it's own implementation in B so its the one who is called. But if you put a super.m1() in there, A.m1() is called again, "A.m1()" is printed again and B.m2() is called again and so on. Got it?
0

A.m1() -->Prints "A.m1()" because you are calling this method from you the main method.

A.m1() method also calls this.m2() inside it. This will go in the method m2() and print -->"A.m2()"

**Note that this.m2() is the same thing as just calling m2().

A.m2() -->Prints "A.m2()" because you are calling this method from the main.

Now for the slightly tricky part.

B.m1(), As you can see, BClass does not have a m1() method but it inherits it from AClass. By inheriting from AClass, BClass Have (internally) all the public and protected methods of AClass. This means BClass now has a m1() method (the same one as AClass). Therefore, calling B.m1() will print AClass m1() --> "A.m1()".

Now remember that A.m1() also calls this.m2() inside of it. But since BClass also have an m2() method, Java will use that one instead and this will end up printing --> "B.m2()".

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.