public class A {
public void f1(String str) {
System.out.println("A.f1(String)");
this.f1(1, str);
}
public void f1(int i, String str) {
System.out.println("A.f1(int, String)");
}
}
public class B extends A {
@Override
public void f1(String str) {
System.out.println("B.f1(String)");
super.f1(str);
}
@Override
public void f1(int i, String str) {
System.out.println("B.f1(int, String)");
super.f1(i, str);
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.f1("Hello");
}
}
I'm seeking that this code would output:
B.f1(String)
A.f1(String)
A.f1(int, String)
Yet I'm getting:
B.f1(String)
A.f1(String)
B.f1(int, String)
A.f1(int, String)
I understand that under the context of B "this" in A.f1(String) is B's instance.
Do I have the option to do the chain new B1().f1(String) -> (A's) f1(String) -> (A's) f1(int, String) ?
This is a theoretical question, practically the solution would obviously be in A to implement a private function that both f1(String) and f1(int, String) would call.
Thank you,
Maxim.
Unfortunately, no
As i'm sure you're aware, but I'll state explicitly for completeness - there are only the 2 keywords to control the method invocation:
- this -
this.method()
- looks for method starting from the invoking instance's class (the instance's "top" virtual table - implied default)
- super -
super.method()
- looks for method starting from the parent class of the class in which the invoking method is defined (the invoking class' parent's virtual table - not strictly true, but simpler to think of this way - thanks @maaartinus)
I can imagine another keyword (e.g. current?) do what you describe:
- current -
current.method()
- looks for method starting from the class in which the invoking method is defined
but Java doesn't have such a keyword (yet?).
I'm afraid, it's impossible, but there's a simple workaround:
public class A {
public void f1(String str) {
System.out.println("A.f1(String)");
privateF1(1, str);
}
private void privateF1(int i, String str) {
System.out.println("A.f1(int, String)");
}
public void f1(int i, String str) {
privateF1(i, str);
}
}
Overridden methods in Java are dynamically bound. i.e. the type of the actual instance of the object dictates what will be called. final
methods (which can't be overridden) and private
methods (which can't be inherited) are statically bound.
In C++, for contrast, you'd have to explicitly make the functions virtual
to get the same behaviour.
package main;
public class A {
public void f1(String str) {
System.out.println("A.f1(String)");
if (this instanceof B)
new A().f1(1, str);
else
this.f1(1, str);
}
public void f1(int i, String str) {
System.out.println("A.f1(int, String)");
}
}
class B extends A {
@Override
public void f1(String str) {
System.out.println("B.f1(String)");
super.f1(str);
}
@Override
public void f1(int i, String str) {
System.out.println("B.f1(int, String)");
super.f1(i, str);
}
public static void main(String[] args) {
A a = new B();
a.f1("Hello");
}
}