2012-09-15 75 views
12

當重寫超類的方法時,Java允許返回類型是協變的。爲什麼Java中的逆變參數類型不允許覆蓋?

爲什麼在重寫方法時允許使用逆變參數類型而不是

+4

可能的重複[爲什麼沒有重寫的參數反差?](http://stackoverflow.com/questions/2995926/why-is-there-no-parameter-contra-variance-for-overriding) –

+0

謝謝。我已經看到了這一點,但很難理解C++中的答案,因爲我完全不熟悉C++。認爲專門尋找Java可能更容易。 – Will

+0

我閱讀鏈接的帖子,據我瞭解,從這個功能獲得的收益並不超過驚喜因素。爲特定實現提供重載方法並不難。我的意思是你看到了這個功能的其他用例嗎?除了直接調用類的方法? –

回答

15

因爲那叫做overloading

特別是,返回類型可以是協變的,因爲它在重載時不被考慮,因此它仍然匹配超類或接口的實現。超載時會考慮參數。與Number doSomethingWithNumber(Number value)相比,您很可能會對Number doSomethingWithNumber(Integer value)進行優化。

+0

假設它具有逆變參數仍然是壓倒性的,我們會遇到什麼問題?我正在尋找像這樣的東西:http://stackoverflow.com/a/2996901/715236,但是如果有一個子類中的方法在超類中覆蓋多個,會有什麼不好? – Will

+0

最大的問題是無法在鏈中某處發生任何基本類型過載時提供重載。這會破壞多態函數調用,因爲查找必須從簡單的等號簽名變爲相同或更基本的簽名,並且如果您同時具有相同或更基本的簽名,應該調用什麼函數,而是調用更具體的函數呢?從設計的角度來看,如果'A擴展B','B擴展C',但'B'從鏈接提供'void f(Object o)'實現,那麼'A'沒有機會實現更多特定的重載方法。這將是一場噩夢。 – pickypg

+1

最重要的是,我認爲這會導致API被延遲地覆蓋,這會導致很多令人難以置信的醜陋的,樣板代碼在內部被用來調用適當的方法:void f(Object o){if( o整型實例)f((Integer)o); }'。然後你不得不問,甚至會如何工作?爲了允許重載行爲,這意味着'Object'參數方法會覆蓋'Integer'參數方法,因此上面的代碼會導致無限的遞歸循環(直到堆棧溢出),因爲它會回落到'對象'方法。 – pickypg

相關問題