我相信這之前必須一直在問,但我似乎無法找到一個類似的例子。我非常瞭解多態性與方法重載,但這裏是一個可以解決的看似簡單的場景,我想不起來了:多態性處理參數 - 簡單的OO?
,讓我們說,我有幾個派生類的基類。我會用形狀在這個例子
base Shape
derived Circle extends Shape
derived LineSeg extends Shape
等
現在,形狀有一個名爲方法相交(其他),對另一種形狀的測試,看看他們是否相交。使用多態性很容易看到Circle,LineSeg等如何實現自己的「相交」方法,並且通過方法重載,我可以輕鬆實現所有需要的組合。例如,
Circle.intersect(LineSeg)
Circle.intersect(Circle)
LineSeg.intersect(Circle)
等
到目前爲止好。
的問題是,如果我保持形狀的中心名單,我想這樣做:
for some shape s
Foreach shape in Shapes
if (s.intersect(shape)) - do something
目前,我不知道這是怎麼可能的,因爲方法的重載選擇「相交」方法來匹配基本類型Shape,而不是適當的參數類型。如何在沒有if-else鏈的情況下檢查類型和向下轉換?
順便說一句,我使用Java,但我不知道該語言是完全相關的,因爲它似乎是一個基本的設計問題。似乎很簡單,我錯過了什麼?
謝謝!
解決下面(謝謝!),看到細節那裏。基本上,由具有在派生類然後調用適當的方法(一個訪問者模式?)回調,則可以使用「這」關鍵字調用適當的交叉方法,因爲它具有所需的正確類型。
有些編程語言支持的論點運行時類型更直接超載。例如,LISP支持* multimethods *,並且我認爲一些函數式編程語言支持相同。在Java中,這通常稱爲* double dispatch *,而GoF Visitor模式則是要走的路。 –
不要挑剔你的設計,但你的繼承有點不對。線段並不是真正的形狀。他們組成形狀。你會檢查任何一個很多的交集,這取決於形狀,組成這兩個形狀的線段:) – ChiefTwoPencils
@ C.Lang,很好的捕獲,但如果我將lineSeg重命名爲「牆」,會怎麼樣?多數民衆贊成基本上是如何使用它,但稱它lineSeg使它更容易概念化使用它在其他更復雜的形狀 – user1922401