我知道重载的方法是在编译时根据调用该方法的引用类型确定的,而重写的方法是由调用该方法的引用的实际对象类型确定的,问题是为什么多态性只与重写和重载无关?
4 回答
使 Java 中的多态成为可能的实现机制是基于其第一个参数的运行时类型的方法的动态分派(在 calla.method(b, c)
中,a
可以认为是方法的第一个参数)。因此,Java 是一种单调度OOP 语言。结果是所有其他参数不参与此机制,并且它们的类型在编译时静态确定。因此,例如,如果您有
class MyObject {
public boolean equals(MyObject o) { ... }
}
进而
MyObject m1 = new MyObject();
Object o = new MyObject();
System.out.println(m1.equals(o));
true
由于没有调用您的方法,因此永远无法打印。编译器看到一个调用MyObject.equals(Object)
并将其编译为对继承方法的调用Object.equals(Object)
。运行时方法分派机制只会决定equals(Object)
调用哪个覆盖方法。
顾名思义,多态是指“相同形式”的方法在不同的上下文中表现出不同的行为。术语“相同的形式”意味着“相同的签名”。这意味着您不能将多态性与重载方法联系起来,因为它们一开始就有“不同的形式”。另一种思考方式是——您需要一个类型和一个子类型来查看多态性的作用——重载方法再次在单个类的上下文中定义。
这是出于技术原因。通常只有this
作为方法隐藏的第一个参数的指针在运行时被分析以确定要调用的方法。
当也分析其他参数时,它被称为Multiple Dispatch。有一些语言本身就支持多分派。
你对此感到困惑。
Overloading
是指在同一类(不是层次结构)中选择具有相同名称但不同签名的方法之一。
Overriding
根据父类继承的方法中的运行时类型,在同名方法中选择。
如果您有一个具有相同名称和签名的方法的基类和派生类,那么这是overriding
在运行时确定正确的。
编译器在同一类overloading
中选择正确版本的方法来使用。
无需查找运行时类型。编译器可以在编译时解决这个问题