重载是编译时多态性。真?
我确实知道覆盖和重载之间的语法差异。我也知道重写是运行时多态性,重载是编译时多态性。但我的问题是:“重载真的是编译时多态性吗?方法调用真的在编译时求解吗?为了澄清我的观点,让我们考虑一个示例类。
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
在Java中,所有非静态方法都是缺省情况下的“虚函数”。只有标有关键字 final(无法覆盖)的方法以及未继承的私有方法才是非虚拟的。
由于虚函数是在运行时使用动态方法调度解析的,并且由于所有非私有、非最终方法都是虚拟的(无论是否重载),因此必须在运行时解析它们。右?
那么,如何在编译时仍然解决重载问题呢?或者,我有什么误解,还是我错过了什么?