2013-07-05 54 views
0

我真的很希望我只是錯過了一些簡單的東西,但我正在閱讀以下內容:http://docs.oracle.com/javase/tutorial/java/IandI/override.html@Override on子類中的方法「出現」在運行時被忽略

我有兩個類和一個接口。從字面上看這個Oracle文檔頁面中顯示的「用例」。然而,當我運行JUnit測試 - 只有在超類中的方法被調用和方法具有簡單的默認,我不想叫:

接口包含此方法的簽名:

public interface RecordServiceInterface { 
    List<String> searchRecords(String id) throws ServiceException; 
} 

實現接口的超類包含默認的這個方法 - Eclipse IDE在找到未實現類的缺少方法時插入此方法。

public class RecordService implements RecordServiceInterface { 
    public List<String> searchRecords(String id) throws ServiceException { 
     // TODO Auto-generated method stub 
     return null; 
    } 
} 

在運行時,只有上面的代碼被調用,因爲我每次都要通過調試器。

子類則擴展了超類,並且有一個要替換的真正落實:

public class MyRecordService extends RecordService { 
    @Override 
    public List<String> searchRecords(String id) throws ServiceException { 
     List<String> myList = new ArrayList<String>(); 

     // ... 

     return myList; 
    } 
} 

我必須完全缺少的@Override點。在執行期間,它反覆無法使用@Override註釋進入方法。

+1

您能否包含測試的來源? –

回答

2

@Override註釋所做的所有事情是,如果在類繼承的任何地方都沒有相應的方法可以被覆蓋,那麼編譯器會生成一個錯誤。所以它的目的是確保你重寫的方法實際上覆蓋了某些東西。

如果你的MyRecordService方法沒有被調用,而是來自RecordService類的方法,那麼我會猜測錯誤的對象是實例化的。所以你面前的是RecordService類型的對象,而不是MyRecordService類型的對象。

由於您沒有提供代碼的這一部分,這只是一個猜測,基於您的繼承看起來很好的事實。

+0

1月 - 非常感謝...我發現了這個問題,它與我被這些類實例化的方式絆倒了,因爲您已經暗示了這一點。我實際使用的超類,使用帶有getInstance()方法的單例模式。 getInstance()方法需要根據傳入的2個構造函數參數的值將正確的類參數傳遞給synchronized()方法。我添加了該邏輯來進行區分,現在它可以正確執行。真誠感謝您的時間和意見。 – mcs130

+0

不客氣。隨意標記我的答案是正確的,然後;-) –

0

@Override是一個編譯時註釋,用於驗證註釋的方法實際上是否覆蓋超類/接口的某些內容。它不影響運行時行爲。

發佈您的測試代碼,以便我們可以更清楚地瞭解您要做的事情。

0

正如您在@Overridejavadoc中看到的那樣,@Override的保留策略爲SOURCE。換句話說:它在編譯時使用,但不會生成二進制代碼(類文件)。

特別地,SOURCE保留策略是defined爲:

註釋是由編譯器被丟棄。

0

@Override有效僅僅是一個試圖重寫super class「或instance的方法,以及偶爾的嘗試覆蓋final方法(設計不可重寫)時趕上錯別字方式。

當給定選擇要調用的內容時,覆蓋的行爲使得覆蓋方法的方法得以實現。

例如:

RecordServiceInterface service = new RecordService(); 
RecordService service2 = new RecordService(); 

與這兩個serviceservice2,從RecordService實施將被調用。現在考慮:

RecordServiceInterface service3 = new MyRecordService(); 
RecordService service4 = new MyRecordService(); 
MyRecordService service5 = new MyRecordService(); 

隨着service3service4,並且service5,從MyRecordService實施將被調用。

覆蓋不會替代父類型的方法,除非它是鏈的一部分(例如,在最後一個塊中創建的所有三個實例,即35)。如果Object的實例不是這種類型(在這種情況下爲MyRecordService),那麼該方法的行爲不會被覆蓋。 serviceservice2仍然會調用RecordService的實現。

這可能是另一個例子更加清晰:

public interface Runnable { 
    void run(); 
} 

public class RunnableA implements Runnable { 
    @Override 
    public void run() { System.out.println("A"); } 
} 

public class RunnableB extends RunnableA { 
    @Override 
    public void run() { System.out.println("B"); } 
} 

public class RunnableC implements Runnable { 
    @Override 
    public void run() { System.out.println("C"); } 
} 

你只能有其中任何一個實例,所以它會每instance.run()通話只能輸出一行。它取決於實例的實現,而不是類路徑中的存在。