我确实知道覆盖和重载之间的语法差异。而且我也知道覆盖是运行时多态性,而重载是编译时多态性。但我的问题是:“重载真的是编译时多态性吗?方法调用真的在编译时解决吗?”。为了澄清我的观点,让我们考虑一个示例类。
public class Greeter {
public void greetMe() {
System.out.println("Hello");
}
public void greetMe(String name) {
System.out.println("Hello " + name);
}
public void wishLuck() {
System.out.println("Good Luck");
}
}
由于所有方法greetMe(), greetMe(String name), wishLuck()
都是公共的,它们都可以被覆盖(包括重载的),对吧?例如,
public class FancyGreeter extends Greeter {
public void greetMe() {
System.out.println("***********");
System.out.println("* Hello *");
System.out.println("***********");
}
}
现在,考虑以下代码段:
Greeter greeter = GreeterFactory.getRandomGreeter();
greeter.greetMe();
该getRandomGreeter()
方法返回一个随机Greeter
对象。它可以返回 的对象Greeter
或其任何子类,如FancyGreeter
或GraphicalGreeter
或任何其他子类。将getRandomGreeter()
使用new
或动态加载类文件创建对象,并使用反射(我认为反射是可能的)或任何其他可能的方式创建对象。所有这些方法Greeter
可能会或可能不会在子类中被覆盖。所以编译器无法知道某个特定的方法(重载与否)是否被覆盖。对?此外,维基百科在Virtual functions上说:
在 Java 中,所有非静态方法默认都是“虚拟函数”。只有用关键字 final 标记的不能被覆盖的方法,以及不能被继承的私有方法是非虚拟的。
由于虚函数是在运行时使用动态方法分派解决的,并且由于所有非私有、非最终方法都是虚拟的(无论是否重载),它们必须在运行时解决。对?
那么,如何在编译时解决重载问题?或者,有什么我误解了,或者我错过了什么?