Java 重载和重写

2022-09-02 01:00:25

我们总是说方法重载是静态多态性,覆盖是运行时多态性。我们在这里所说的静态到底是什么意思?对方法的调用是否在编译代码时解析?那么,普通方法调用和调用最终方法有什么区别呢?哪一个在编译时链接?


答案 1

方法重载意味着根据输入创建函数的多个版本。例如:

public Double doSomething(Double x) { ... }
public Object doSomething(Object y) { ... }

在编译时选择要调用的方法。例如:

Double obj1 = new Double();
doSomething(obj1); // calls the Double version

Object obj2 = new Object();
doSomething(obj2); // calls the Object version

Object obj3 = new Double();
doSomething(obj3); // calls the Object version because the compilers see the 
                   // type as Object
                   // This makes more sense when you consider something like

public void myMethod(Object o) {
  doSomething(o);
}
myMethod(new Double(5));
// inside the call to myMethod, it sees only that it has an Object
// it can't tell that it's a Double at compile time

方法重写意味着通过原始方法的子类定义方法的新版本

class Parent {
  public void myMethod() { ... }
}
class Child extends Parent {
  @Override
  public void myMethod() { ... }
}

Parent p = new Parent();
p.myMethod(); // calls Parent's myMethod

Child c = new Child();
c.myMethod(); // calls Child's myMethod

Parent pc = new Child();
pc.myMethod(); // call's Child's myMethod because the type is checked at runtime
               // rather than compile time

我希望这有帮助


答案 2

你是对的 - 对重载方法的调用是在编译时实现的。这就是为什么它是静态的。

对重写方法的调用是在运行时根据调用方法的类型实现的。

关于虚拟方法,维基百科说:

在Java中,所有非静态方法都是缺省情况下的“虚函数”。只有标有关键字 final 的方法才是非虚拟的。

final方法不能被覆盖,因此它们是静态实现的。

想象一下方法:

public String analyze(Interface i) {
     i.analyze();
     return i.getAnalysisDetails();
}

编译器不能重载此方法,因为可以传递给它的所有实现都可以传递给它。Interface