2014-06-25 71 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的