在静态方法覆盖的情况下..我已经开发了以下代码
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();
在此阶段我仍然得到类getF();
的方法Ab
,请提供建议
答案 0 :(得分:5)
您无法覆盖静态方法。
静态方法属于类。您可以拨打Ab.getF()
或Ham.getF()
- 您在编码时选择了哪个。
在类层次结构中命名相同的静态方法没有任何影响(除了程序员可能的混淆)。静态方法是属于类的浮动代码,而不是实例。只有实例方法对覆盖很敏感。
由于这个原因,在实例上调用静态方法(就像你一样)是不好的,因为它使得该方法看起来像是一个实例方法。它在语言中被允许,但导致程序员混淆,因此导致错误,特别是如果静态方法具有类似实例方法的名称 - 例如,发现名为setName(String)
的方法是静态方法可能是合理杀人罪的理由。
答案 1 :(得分:4)
在编译时,实例调用的静态方法被编译为调用变量被声明为的类,而不是实际实例化的类,因此a.getF();
将导致Ab.getF();
并且不是Ham.getF();
。
通常使用实例而不是类名调用静态方法是一种非常糟糕的做法。 (我认为最好的例子是在Thread.sleep()
实例上调用thread
,假设它会导致实例线程进入休眠状态,但实际上当前线程将会休眠)
答案 2 :(得分: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 很奇怪
答案 3 :(得分:0)
首先,你不能调用派生类中带有名称和签名的静态方法与基类相同的情况。覆盖的情况。
这是因为在重写的情况下,编译器不会为函数调用生成字节代码,因为调用实际方法会在运行时解析,具体取决于 引用变量的多态行为。
覆盖实际上是由编译器的这种动态行为定义的(而不是由具有相同签名方法的基类和子类定义,这些只是覆盖的前提条件)。
静态方法是类实体,因此绑定到引用变量而不是运行时对象,因此方法调用仅在编译时解析(基于引用变量的类型,或者由类引用的类名。
同样,如果在超类和子类中都有公共实例变量或具有相同名称和类型的静态变量,则将选择具有变量类型的变量而不是运行时对象。