2013-08-04 89 views
1

所以我知道在Java中,当你有你应该与格式ClassName.method()调用它,而不是使用相同的结构,你会为实例方法,即静态方法:但是,如果你在Java中继承静态方法?

ClassName myObject = new ClassName(); 
myObject.method(); 

要这样做它仍然是有效的代码,并会工作。比方说,我决定这样做,其中有问题的方法是静态的,并且具有以下设置:

public SuperClass { 
    public static int foo(int x) { 
     return x; 
    } 
} 

public SubClass extends SuperClass { 
    public static int foo(int x) { // Overriding foo() in SuperClass 
     return x + 1; 
    } 
} 

public MyDriver { 
    public static void main(String[] args) { 
     SuperClass myObject = new SubClass(); // Upcasting. 
     System.out.println(myObject.foo(5)); // This should polymorphically print 6 
    } 
} 

什么打印出屏幕上,但是,5而不是6.为什么?

回答

5

静态方法仅适用于它们在其中定义的类,并且它们不能被覆盖。

当你调用myObject.foo(5),您呼叫在现实SuperClass.foo(5),因为你宣布myObjectSuperClass,无论你是实例为一体。

正确的方法调用静态方法是直接从它被声明在类调用它,所以如果你想叫SubClass.foo(),你必须从显式声明的​​实例调用它(意味着没有上传),或者你需要像这样调用SubClass.foo()

简单的答案是,从实例调用静态方法的计算结果是从声明的类型调用那些没有实例而不是实例类型的相同方法。

我不确定这一点,但如果将代码编译为字节码时,我不会感到惊讶,实例静态方法调用实际上会编译为直接调用声明的类型。

编辑:upvote把我的注意力带回了这一点,我清理了解释,使其更加清晰,并修复了我的一些可以忽略的语法错误。我希望这有助于未来的读者。

1

静态方法不依赖于实例,它们属于类而只属于类,事实上,如果你有一个静态方法,你将总是访问一个唯一的实例。

myObject.foo(5) 

只是一个快捷方式,你真正做的是

SuperClass.foo(5) 
+0

这不是真的只有一个实例,它是每个虚拟机一个,如果你有一个以上的虚拟机,你可能有多个实例。 – luisZavaleta

+2

+1,但取决于ClassLoader体系结构,它甚至可能会超过每个JVM一个;例如OSGi。 – earcam

1

使用一个类的实例来调用这个类的静态方法是你应该避免,因为它可能会导致混乱。如果您需要多态调用任何方法,请将其设为实例方法。你不能多态地调用静态方法。 SuperClass调用被调用的原因是因为这是编译时myObject的明显类。这种效果也可以被看作在以下情形:

public void doSomething(SuperClass param) { 
    System.out.println("SuperClass"); 
} 

public void doSomething(SubClass param) { 
    System.out.println("SubClass"); 
} 

public void test() { 
    SuperClass myObject = new SubClass(); 
    doSomething(myObject); 
} 

如果测试()被调用,SuperClass将被打印。

0

静态方法被JVM视为全局对象,它们根本没有绑定到对象实例。顺便说一句,你只能重载静态方法,但你不能重写。因此请检查"Oracle Documentation for Overriding and Hiding Documents"

定义一个方法具有相同签名作为父类的方法:

--------------------------- --------------超类的实例方法超类静态方法      
子类的实例方法            重写                                                                         产生编译时间错误
子类静态方法                        产生编译时间错误     隐藏