2014-06-25 72 views
0

这里如果我尝试覆盖静态方法而不在子类中使用static,它会给我一个错误..虽然这不是静态变量。为什么?使用“非静态”方法/字段覆盖“静态”方法/字段

class A { 
    static int a; 
    static void a() { 
     System.out.println("in A"); 
    } 
} 


class B extends A { 
    int a=9;/*this does not give an error*/ 
    void a()/*this statement gives an error*/ { 
     System.out.println("In B"+(A.a)); 
    } 
} 


class Test { 

    public static void main(String []args) { 
     B b1=new B(); 
     b1.a();   
    } 
} 
+5

重写不适用领域。 –

+1

http:// stackoverflow。com/questions/2223386/why-doesnt-java-allow-overriding-of-static-methods –

+1

你不能覆盖静态方法,你会隐藏它们。 – Pshemo

回答

0

该字段不可超越。

它与Java的命名范围有关。 Java可以用比方法更少的歧义来解析字段名称。

在B中,JVM不知道,如果你想打电话机管局()或Ba()

0

答案是: 静态应用于方法意味着您可以访问该方法没有实例的对象该类应用于变量意味着您无法在代码中修改该变量。 另外,override并不关心你实际覆盖的方法中的变量。 这是因为override正在用新的替换方法。 实施例中的伪代码

Class Triangle { 
    public method calcArea() { 
      // generic method 
     } 
} 

Class RightTriangle extend Triangle { 
     public method calcArea() { 
      // area needs to be calculated in different way, so I specify a new Area method 
     } 
} 

Class Main { 
     public Main() { 
      Triangle a; 
      RigthTriangle b; 
      a.calcArea(); // Calling Triangle.area! 
      b.calcArea(); // calling RightTriangle.area! 
     } 
}    
0

这是因为一些奇怪的原因,static方法实际上可以通过参考援引。要调用的静态方法基于参考的类型,而不是对象,这意味着允许具有与static方法相同签名的实例方法会对要调用的方法产生歧义。

例如,如果这被允许:

class A { 
    static void method() { 
     System.out.println("A"); 
    } 
} 

class B extends A { 
    void method() { 
     System.out.println("B"); 
    } 
} 

class Main { 
    public static void main(String[] args) { 
     A b = new B(); 
     b.method(); 
    } 
} 

会发生什么?是否A的实现被调用,因为bA的参考?或者应该调用B的实现,因为bB对象?

因为这两个选项同样有效,所以允许实例方法“覆盖”static方法,确保所有方法调用都是有效的。现在


,这不是场(静态和非静态)真实的,因为字段不能在子类中重写,只是隐藏起来。所以编译器可以根据引用的类型很容易找出你想要的字段。

+0

我的问题是为什么这个事情不会发生在静态变量?即静态变量可以被覆盖(阴影),而不使用静态变量。 – NeelPatwa

+0

阅读我的最后两句话。它们适用于变量是否是静态的 – awksp

0

静态方法不显示运行时多态性。因此,通过规则,静态方法在编译期间得到解决。通过声明一个静态方法,你就隐藏了它。所以没有子类可以看到它。但这是可能的。

class A { 
    static void test() { 
     System.out.println("A"); 
    } 
} 

class B extends A { 
    static void test() { 
     System.out.println("B"); 
    } 
} 

这是因为B中的test()是B的方法,A中的test()是A的编译器可以理解的方法。所以,如果你运行该 类测试{

public static void main(String []args) { 
    B b1=new A(); 
    b1.test();   
} 

在编译时看到B1编译器的引用类型都知道,您所呼叫B的测试,即使在运行时,对象将是A的