David W
David W

Reputation: 17

Inheritance, Polymorphism Questions

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!

Upvotes: 0

Views: 294

Answers (4)

sga4
sga4

Reputation: 370

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

Upvotes: 1

hermit
hermit

Reputation: 1107

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.

Upvotes: 1

Rana
Rana

Reputation: 1755

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()".

Upvotes: 0

Everv0id
Everv0id

Reputation: 1980

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();
    }
}

Upvotes: 0

Related Questions