2016-06-07 111 views
2

是否有一種語言允許超類型A定義了一個方法useFoo(Foo foo),例如B,派生自A定義了一個方法useFoo(Bar bar),(Bar源自Foo),當使用B作爲A時, Foo這是一個Bar,它會運行useFoo的最專業版本?是否有一種語言允許動態綁定參數?

Java示例(不工作,不幸):

public class Foo { 

} 

public class Bar extends Foo { 

} 


public class A { 
    void useFoo (Foo foo) { 
     System.out.println("A"); 
    } 
} 

public class B extends A { 
    void useFoo (Bar bar) { 
     System.out.println("B"); 
    } 
} 

public static void main(String[] args) { 
    A b = new B(); 
    b.useFoo(new Bar()); // actually returns "A", is there one returning "B" ? 
} 

我知道有一種方法可以做到這一點與「幾」線(例如使用訪問者),但我想知道,如果任何(編譯的)語言都會允許它。

我承認我想知道這是否甚至可能,相反,我不會感到驚訝,什麼阻止它?

這個概念有更好的名字嗎?

編輯:在java中,它被命名爲逆變。謝謝@Kevinrob

+1

在Java中,它是「協方差」和「逆變」,[見更多](http://stackoverflow.com/a/2501513/244702)。 –

回答

1

你的問題涉及到以下概念:

  1. Covariance:參數可以在子類中重新定義爲原來的參數類的子類。例如,該慣例用於艾菲爾。已知該方法導致類型安全問題,CAT-呼叫(CAT =更改可用性或類型),需要以特殊方式解決這一問題以保持類型系統的健全性。協變的強有力論據是,它與合同(例如,按合同設計)很好地結合在一起。
  2. Multiple dispatch:方法調用不僅依賴於調用的目標類型,而且還依賴於參數類型。該頁面列出了支持這種機制的幾種語言。多次調度是處理協方差和逆變的一種方法。但是,在設計依賴機制的方法集以避免在運行時執行意外的方法時,必須小心。
  3. Generic programming:而不是供應商固定參數類型,它們可以由客戶端修復。該機制是類型安全的,並且不存在前兩者的問題,但它要求客戶端明確指定實際的泛型參數,並且如果太多這樣的參數,類型聲明可能會變得笨拙。現在有很多支持它的語言。
+0

我真的看到#1和#2的重點,但是爲什麼是#3? 在我看來,如果能夠擴展功能性而不必按指數規律編寫代碼(比方說,訪問者必須針對每種可能的情況進行詳細說明),那就更好了。 (雖然冒險,看到你的#2)。你認爲你可以提供更多的信息嗎?讓我清楚,我使用這些技術,我只是好奇。 –

+0

@PierreAntoineGuillaume,#3確實有點偏離原始問題,我已經基於我的個人經驗添加了它:當需要重用代碼,不同的參數和結果類型以及類型安全性時,可以通過以下方式實現:使用泛型類型。例如,你可以用'void useFoo(T foo)'聲明'A ',它可以在'B '中安全地重新定義。然後你會寫'A b = new B ();'和'b.useFoo(new Bar());'會打印出你想要的''B''。 –

+0

我不認爲我會得到更好的答案,因此我關閉了這個問題,但我傾向於認爲它可以處理的方式確實提供了一點調整,具體取決於正在使用哪種語言:在C++中,模板特化會無疑提供了這種功能。我堅持與java atm。哦,非常感謝你的洞察力! –

相關問題