pippo
pippo

Reputation: 35

Java superclass calls subclass method

I have these classes:

class A {
  public void f() { System.out.println("f() in A"); }
  public void g() { System.out.println("g() in A"); f(); }
}

class B extends A {
  public void f() { System.out.println("f() in B"); }
}

Why does

B b = new B();
A a = b;
a.g();

print out this

g() in A
f() in B

and not

g() in A
f() in A

Is there something I am missing?

Upvotes: 3

Views: 123

Answers (5)

Ravindra babu
Ravindra babu

Reputation: 38910

Now you got idea about polymorphism and overriding.

Since you did not get your expected output, I would suggest a way to get your expected output through method shadowing or hiding

If you re-define base class non-static & non-private method in derived class, it's called overriding.

In this example, A holds the instance of B and hence f() has been invoked from B instead of A.

If you re-define base class static method/variable is derived class, it's called hiding or shadowing.

In above example, just add static modified for g() method and you will get required output. Now g() method

class A {
  public static int i=10;
  public static void f() { 
    System.out.println("f() in A:i="+i); 
  }
  public void g() { System.out.println("g() in A"); f(); }
}

class B extends A {
  public static int i=20;
  public static void f() { 
      System.out.println("f() in B:i"+i); 
  }
}
public class Test2 {
    public static void main(String args[]){
        B b = new B();
        A a = b;
        a.g();
    }
}

output:

g() in A
f() in A:i=10

Upvotes: 0

Jack
Jack

Reputation: 133587

This is because Java uses dynamic dispatch by default (and forcibly) on methods of classes.

This feature makes sure that, when a method is called, the most specialized version of it it is chosen to be executed. In your case, since B extends A, it means that public void f() implementation of B is more specialized than the one of A. So although A a is statically of type A, it's dynamically of type B and that method is chosen.

Upvotes: 3

Kevin Klute
Kevin Klute

Reputation: 458

The reference variable type of an object determines which methods are accessible.

The class of an object determines which methods exist. These methods that exist but are not accessible can be accessed through casting.

i.e: ((B) a).g(); Will allow you to access the B version of G. This only works because underneath a is a B.

Upvotes: 0

Dries De Rydt
Dries De Rydt

Reputation: 808

https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html

This is called polymorphism. It lets us do things like hold a list of type Animal, but when we put a cat in it, and do animal.performcall() it will print a meow. This is the example my teacher gave me many years ago, anyway :)

Upvotes: 1

DBug
DBug

Reputation: 2566

Yes, even though variable "a" is of type A, the object reference it holds is of type B, so f() in B is what's called.

Upvotes: 2

Related Questions