为什么我们说Java中的静态方法不是虚方法?

Lio*_*ion 6 java

在面向对象的范例中,函数或虚方法是一种函数或方法,其行为可以通过具有相同签名的函数在继承类中重写,以提供多态行为.


根据定义,除了final方法和私有方法之外,Java中的每个非静态方法都是默认的方法.不能为多态行为继承的方法不是虚方法.


Java中的抽象类只不过是与C++等效的纯虚方法.


为什么我们说Java中的静态方法不是虚方法?即使我们可以覆盖静态方法,因此它可以提供多态性的一些优点,并且Java中的静态方法可以主要使用它的关联类名调用,但也可以使用它的关联类的对象来调用它.Java与调用实例方法的方式相同.

Jon*_*eet 17

无法覆盖静态方法.它们在编译时受到约束.它们不是多态的.即使你试图调用它就像它是一个实例方法(你不应该做的IMO),它绑定到该表达式的编译时类型,并且完全忽略执行时间值(即使它为null) :

Thread otherThread = null;
otherThread.sleep(1000); // No errors, equivalent to Thread.sleep(1000);
Run Code Online (Sandbox Code Playgroud)

这种行为对于读者来说可能非常混乱,这就是为什么至少某些 IDE允许您生成警告或错误以"通过"引用访问静态成员.这是Java设计中的一个缺陷,纯粹而简单 - 但它根本不会使静态方法变得虚拟.


Jer*_*myP 5

假设你有A类

public class A
{
    public static void doAStaticThing()
    {
        System.out.println("In class A");
    }
}
Run Code Online (Sandbox Code Playgroud)

和乙

public class B extends A
{
    public static void doAStaticThing()
    {
        System.out.println("In class B");
    }
}
Run Code Online (Sandbox Code Playgroud)

另一个类中的方法如下:

public void foo()
{
    B aB = new B();
    bar(B);
}

public void bar(A anA)
{
    anA.doAStaticThing(); // gives a warning in Eclipse
}
Run Code Online (Sandbox Code Playgroud)

您将在控制台上看到的消息是

In class A
Run Code Online (Sandbox Code Playgroud)

编译器查看了anA方法 bar 中声明的类型并静态绑定到类 A 的实现doAStaticThing()。该方法不是虚拟的。