2012-05-05 95 views
0

在静态方法重载的情况下..我有下面的代码开发了这个关于静态方法覆盖

class Ab { 
    static void getF() { 
     System.out.println("I am saral"); 
    } 
} 

class Ham extends Ab { 
    static void getF() { 
     System.out.println("I am saral saxena"); 
    } 
    public static void main(String[] args) { 
     // Ham h = new Ham(); 
     // h.getF(); //Ham 
     Ab a = new Ham(); 
     a.getF(); // Ab class 
    } 
} 

现在我的查询是静态方法重载的情况下,当我使用在这个阶段多态行为,Ab a = new Ham();我仍然得到类Ab的方法getF();,请告知。

回答

5

不能覆盖静态方法。

静态方法属于类。你可以拨打Ab.getF()Ham.getF() - 你选择了你的代码。

在类层次结构中命名静态方法不会有什么影响(除了可能导致程序员混淆)。静态方法是属于类的代码的浮动位,而不是实例。只有实例方法对重写非常敏感。

由于这个原因,在实例上调用静态方法的风格很差(因为它使得该方法看起来像是一个实例方法)。它在语言中是允许的,但会导致程序员混淆,因此会导致错误,特别是如果静态方法的名称类似于实例方法 - 例如发现名为setName(String)的方法是一种静态方法,则可能是合理的杀人理由。

+0

@ Bohemian..yeah that这个概念是静态方法隐藏不被覆盖 – dghtr

+1

否 - 它们不是隐藏的(或被称为* shadowed)。静态方法没有这样的概念。 – Bohemian

+0

谢谢,请您详细解释一下。 – dghtr

4

在编译时,如调用该变量声明为,而不是实际实例类,所以a.getF();将导致是Ab.getF();而不是Ham.getF();类是通过实例调用静态方法编译。

这是一个非常不好的做法,通常用实例调用静态方法而不是类名。 (我觉得最好的例子就是在thread实例调用Thread.sleep(),假设它会导致实例线程睡眠,但实际上当前线程)

0

覆盖静态函数是不可能和无用的(我避免使用术语方法,因为方法涉及到对象)。

当有需要调用取决于对象的类别不同的​​静态功能,做这种方式

class Ab { 
private static void getF() { 
    System.out.println("I am saral"); 
} 
public void doit() { 
    getF(); 
} 
} 
class Ham extends Ab { 
private static void getF() { 
    System.out.println("I am saral saxena"); 
} 
@Override 
public void doit() 
{ 
    getF(); 
} 
public static void main(String[] args) { 
    Ab a = new Ham(); 
    a.doit(); // Ham class 
} 

}

顺便说一句,使用得到一个函数返回void很奇怪

0

第一件事是你不能调用派生类中具有名称和签名的静态方法与在基类中一个重写的情况。

这是因为在重载的情况下,编译器不会生成函数调用的字节代码,因为实际的方法将被调用在运行时根据 来解析参考变量的多态行为。

覆盖实际上是由编译器的这种动态行为定义的(而不是基类和具有相同signatured方法的子类,这些只是覆盖的前提条件)。

静态方法是类的实体,并因此结合到参考变量,而不是运行时间对象,从而如果通过将其称为方法调用在仅编译时(基于参考变量,或类名的类型解决。

同样,如果你有公共实例变量或静态变量在超类和子类中都具有相同的名称和类型,那么将选择具有变量类型的变量而不是运行时对象。