重载是编译时多态。真?

浏览:47日期:2024-02-21
如何解决重载是编译时多态。真??

如果您要的话,仍然可以重写重载的方法。

重载的方法就像不同的族,即使它们共享相同的名称。编译器会静态地选择一个具有给定签名的系列,然后在运行时将其分派到类层次结构中最具体的方法。

也就是说,方法分派分两个步骤执行:

第一个是在编译时使用可用的静态信息完成的,编译器将为call签名发出一个与您当前的方法参数最匹配的签名,该重载方法在调用该方法的对象的声明类型中的重载方法列表中。第二步在运行时执行,给定应该调用的方法签名(上一步,还记得吗?),JVM将把它分派到接收器对象实际类型中最具体的覆盖版本。

如果方法参数类型根本不是协变的,则重载等效于在编译时修改方法名称;因为它们实际上是不同的方法,所以JVM永远不会根据接收者的类型互换分配它们。

解决方法

我确实知道重载和重载之间的语法差异。而且我也知道,重载是运行时多态,重载是编译时多态。但是我的问题是:“重载真的是编译时的多态性吗?方法调用真的在编译时解决了吗?”。为了阐明我的观点,让我们考虑一个示例类。

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的方法(不能被覆盖)以及私有方法(不能被继承)是非虚拟的。

由于虚拟函数是在运行时使用动态方法分派来解析的,并且由于所有非私有,非最终方法都是虚拟的(无论是否重载),因此必须在运行时解析它们。对?

那么,如何在编译时解决重载呢?或者,是否有我误解的东西,或者我想念什么?

相关文章: