This is another of those SCJP questions. The code below prints Alpha:fooBeta:fooBeta:barBeta:bar
, and I don't understand why the first foo call picked Alpha's foo instead of Beta's. If the Alpha.foo parameter is changed to String instead of String..., then the output is Beta:fooBeta:fooBeta:barBeta:bar
which makes sense.
My understanding is that when you say Alpha a = new Beta();
, the compiler checks for Alpha.foo, but the JVM will actually run Beta.foo. For one thing, Beta does have a foo method whose signature matches the call. For another, I thought varargs methods only run when there's no other method available that matches the call. So that's two reasons I think Alpha.foo shouldn't be run. What part of this understanding is wrong?
Thanks!
class Alpha {
public void foo(String... args) { //if this were String args, then it makes sense
System.out.print("Alpha:foo");
}
public void bar(String a) {
System.out.print("Alpha:bar");
} }
public class Beta extends Alpha {
public void foo(String a) {
System.out.print("Beta:foo");
}
public void bar(String a) {
System.out.print("Beta:bar");
}
public static void main(String[] arg) {
Alpha a = new Beta();
Beta b = (Beta) a;
a.foo("test");//confusing line
b.foo("test");
a.bar("test");
b.bar("test");
} }
Edit: I think I know where I misunderstood things now. I thought that in a SuperClass sc = new SubClass();
situation, whatever method is called on sc will be searched for in SubClass at runtime, although they'll be searched in SuperClass at compile-time. It turns out, as I now think I understand, that whatever method is called on sc will be searched for in SuperClass at both compile-time and run-time, UNLESS SubClass has provided a "better" version of the method. Then, even at compile-time, the compiler will know the method to invoke is the SubClass version.