不支持Java中静态方法的动态多态的原因

时间:2014-07-20 21:25:50

标签: java polymorphism static-methods method-overriding

为什么Java不支持静态方法的动态多态性? 如果答案是“静态方法不应该在实例上调用,因此不需要在运行时解析方法调用”,那么进一步的问题是“为什么Java允许我在实例上调用静态方法?”。为什么不直接通过给出一些编译时错误来阻止用户直接调用实例上的方法。

反过来说,如果Java支持静态方法的Runtime Polymorphism会出现什么问题呢?

4 个答案:

答案 0 :(得分:7)

  

为什么Java允许我在实例上调用静态方法?

你的假设是错误的。它从不调用类的实例。它总是叫上课。

尝试以下示例代码,您永远不会获得NullPointerException

class ABC {
    public static void hello() {
        System.out.println("Hello");
    }
}

ABC abc = null;
abc.hello(); 
  

如果Java支持静态方法的Runtime Polymorphism会出现什么问题?

当您Polymorphism子类中的方法时,

override会出现。因为静态方法属于类,所以没有覆盖静态方法的意义。因此,多态性总是适用于仅属于类实例的方法。

答案 1 :(得分:1)

静态方法是基于变量的类型而不是实例的类来解析的。这允许一些优化,因为在编译时要调用的确切方法始终。允许多态静态方法可以防止这种情况。

允许在实例上调用静态方法的结果如下。

class A {
    static void func() {}
}

class B extends A {
    static void func() {}
}

B b = new B();
A a = b;

b.func(); // calls B.func()
a.func(); // same instance, but calls A.func()

高度混乱,反直觉。基于如何实现静态方法允许在实例上调用静态方法是一个主要的设计缺陷,应该始终避免。

根据定义,静态方法不需要调用实例。通过允许多态调用,您需要一个实例,如果您需要一个实例来确定要调用哪个方法,那么为什么该方法是静态的?

答案 2 :(得分:0)

动态多态可以支持方法覆盖。但是对于静态方法覆盖是不可能的,因为它导致我们隐藏方法。因此,静态方法不支持动态多态性。

答案 3 :(得分:-1)

我很高兴我可以通过类的实例调用静态方法。它允许我无需限定地从实例调用该方法。如果我尝试(合法但非理性地)将通过称为实例,我的IDE会发出警告。

public static void foo() {
    //yadda yadda
}

public void bar() {
    foo(); // this is legal
    MyClass.foo() // this is also legal, but would be necessary if I couldn't call it through the instance
}

// in some other class:
new MyClass().foo() // this is legal but silly and my IDE warns me about it