2013-09-27 89 views
1

考慮followoing代碼器具法鑄造

interface MyInterface{ 
    void method(String s);// if we write static modifier we have compile error 
} 
class MyClass implements MyInterface{ 
    public static void main(String[] args){ 
     myMethod(new Object());//Compile error 
    } 
    static void method(String s){...}// compile error 
    static void myMethod(Number n){...} 

} 
  1. 爲什麼我們不能在接口定義靜態方法?
  2. 爲什麼我們不能器具method()用static修飾符?
  3. 當我們通過引用Object來調用myMethod時,我們有編譯錯誤。據我瞭解,編譯器不會自動投射,不是嗎?
  4. 考慮下面的代碼

    Object someObj; ... Number n= (Number) someObj;

什麼編譯當我們在這種情況下轉換爲Number是幹什麼的?

+0

請參閱[我們爲什麼要將接口方法聲明爲public?](http://stackoverflow.com/questions/9614708/why-should-we-declare-interface-methods-as-public) – Smit

+2

@Smit不同的主題。沒有真正涉及到這個問題 –

+0

你在問幾個不同的問題,每個問題都應該單獨提出。第一種可能的重複[爲什麼我不能在界面中聲明靜態方法?](http://stackoverflow.com/q/21817/1281433)。 –

回答

4

爲什麼我們不能在接口定義靜態方法?

接口的所有方法默認爲public abstract。使用static修飾符沒有意義。因爲靜態方法的調用不是多態的。在某種意義上,你不能重寫它們。您只能在類名稱上調用靜態方法。那麼,你也可以在一些引用上調用它們,但是這將根據所聲明的引用類型最終解決。現在,由於該方法默認爲抽象,所以調用它是沒有意義的。它沒有任何機構來完成任何任務。

爲什麼我們不能用static修飾符工具()的方法?

當您嘗試將static修飾符添加到重寫的方法時,它不被視爲重寫。所以,你的類基本上有兩種不同的方法,具有相同的名稱,相同的參數和相同的返回類型。這當然不能在課堂上進行。

需要注意的是,你必須public修改明確添加到上位法的類,否則你的代碼將無法編譯。原因在於,您無法降低子類中重寫方法的可見性。

當我們調用myMethod參考Object時,我們有編譯錯誤。據我瞭解,編譯器不會自動投射,不是嗎?

java的沒有做自動收縮轉換。您需要明確添加轉換。但即使它允許,你期望你的代碼的行爲,因爲你試圖引用一個超類對象的子類引用?當然,你可以讓你的代碼中加入一投,而調用方法進行編譯:

myMethod((Number)new Object()); // This will compile, but fail at runtime 

以上的調用將導致ClassCastException在運行時。

但是,如果你有一個Object參考指的的Number任何子類的一個對象,你可以添加一個明確的轉換,這將是類型安全的:

Object obj = new Integer(5); 
Number num = (Number)obj; // This is fine. Because `obj` is referring to an `Integer`. 

最後,你main的簽名方法不正確。您錯過了public修飾符。

+0

請注意,來自Java 8 *的接口可以*具有靜態方法。 – arshajii

+0

@arshajii。是的,Java 8具有默認方法,但我不考慮這裏,假設OP尚未使用Java 8。 –

+0

@Rohit Jain當我們投向'Number'時發生了什麼:Object obj = new Integer(5); Number num =(Number)obj;'在你的例子中?編譯器將'(Number)obj'解析爲對'Number'的一些引用? –

2

爲什麼我們不能在接口定義靜態方法?

接口都設計有多態性的工作,基本上是這樣。多態性如何知道在接口上調用靜態方法時要調用哪個實現?

// Should that invoke MyClass.method or MyOtherImplementation.method? 
MyInterface.method("foo"); 

下一頁:

爲什麼我們不能用static修飾符工具()的方法?

這個想法是,該方法被調用一些實現接口的對象 - 這使得它成爲一個實例方法。

當我們調用myMethod參考Object時,我們有編譯錯誤。據我瞭解,編譯器不會自動投射,不是嗎?

沒有,編譯器不會自動轉換。有沒有隱式轉換從ObjectNumber,所以你不能調用方法與Number類型與Object類型的參數的參數。

什麼編譯當我們在這種情況下,投給數是幹什麼的?

它驗證該的someObj值爲null或到的Number或子類的實例的引用。

0

直到JDK7:

  1. ,因爲靜態方法被綁定到類。你通常會這樣調用它們:

    MyClass.method(""); 
    

    你不能覆蓋它們。

  2. 看到1,所有的接口方法是public abstract你不能改變的!

  3. 沒有編譯器不會自動投

  4. 他試圖投和失敗