某個函數返回的對象,須要由函數調用者執行向下轉型 (downcast) 。將向下轉型的動做移到函數中。 java
向下轉型在Java特別盛行,由於Java沒有模板機制,所以若是想從集合之中取出一個對象,就必須進行向下轉型。咱們應該儘可能避免使用向下轉型。若是某個函數返回一個值,而且返回的對象類型比函數簽名所昭告的更特化,即是在函數用戶身上強加了非必要的工做。這種狀況下,咱們就不該該要求用戶承擔向下轉型的責任,應該儘可能爲它們提供準確的類型。這些狀況,一般會在返回迭代器或集合的函數身上發生。此時就應該觀察這個迭代器被用來幹什麼,而後針對性地提供專用函數。 函數
1.找出必須對函數調用結果進行向下轉型的地方。 spa
這種狀況一般出如今返回一個集合或迭代器的函數中 code
2.將向下轉型動做搬移到該函數中。 對象
針對返回集合的函數,使用Encapsulate Collection 編譯器
下面的例子中,以Reading表示「書籍」。還有一個名爲lastReading()的函數,它從一個用於保存Reading對象的vector中返回其最後一個元素: it
Object lastReading(){ return readings.lastElement(); }
咱們應該將這個函數變成: io
Reading lastReading(){ return (Reading)readings.lastElement(); }
當擁有一個集合時,上述那麼作就頗有意義。若是「保存Reading對象」的集合被放在Site類中,而且客戶端代碼以下: 編譯
Reading lastReading = (Reading)theSite.readings().lastElement();
咱們就能夠再也不把向下轉型的工做推給用戶,並得以向用戶隱藏集合: ast
Reading lastReading = theSite.lastReading();
class Site { ... Reading lastReading(){ return (Reading) readings().lastElement(); } }若是修改函數,將其返回類型改成原返回類型的子類,那就是改變了函數簽名,但並不會破壞客戶端代碼,由於編譯器知道它老是能夠將一個子類自動向上轉型爲超類。固然你必須確保這個子類不會破壞超類帶來的任何契約。