首頁 > 後端開發 > C++ > 程式設計中協變和逆變有什麼不同?

程式設計中協變和逆變有什麼不同?

Patricia Arquette
發布: 2025-01-20 17:09:09
原創
142 人瀏覽過

What's the Difference Between Covariance and Contravariance in Programming?

協變與逆變:理解「輸入」與「輸出」的差異

協變和逆變是程式設計中涉及泛型類型如何賦值或從繼承型別或與其相關型別存取的概念。

協變:輸出位置

當原始型別僅用作輸出值時,協變允許使用更通用的(或「更大」)型別來取代更具體的型別。例如,水果列表可以被視為香蕉列表,因為將更具體的類型轉換為更通用的類型沒有任何限制:

<code>List<水果> 水果列表 = new List<水果>();
水果列表.Add(new 香蕉()); // 有效,因为香蕉是水果</code>
登入後複製

逆變:輸入位置

當原始類型僅用作輸入值時,逆變允許將更具體的(或「更小」)類型替換為更通用的類型。這是因為更具體的類型可以安全地縮小到更通用的類型:

<code>MyInterface<基类> 基类接口 = new MyInterface<派生类>(); // 有效,因为派生类是基类</code>
登入後複製

「輸入」與「輸出」表示法

“in”和“out”關鍵字可用來泛型介面定義中,以指定泛型類型參數表示輸出位置還是輸入位置。

  • “out”: 當泛型類型僅用作傳回值時使用。這允許衍生類別隱式轉換為基底類別。
  • “in”: 當泛型型別只用作方法參數時使用。這允許基底類別隱式轉換為衍生類別。

透過指定“in”或“out”,編譯器可以執行安全的強制轉換操作,而無需明確轉換。

實際範例

考慮一個將類型參數作為參數的泛型介面:

<code>interface MyInterface<T> {
    void Process(T value);
}</code>
登入後複製

如果使用逆變實作該介面:

<code>interface MyInterface<in T> {
    void Process(T value);
}</code>
登入後複製

這表示任何衍生類別的任何物件都可以作為參數傳遞給Process方法。當方法中的邏輯只需要基類類型而不管實際物件類型時,這很有用。

另一方面,如果使用協變實作該介面:

<code>interface MyInterface<out T> {
    T GetValue();
}</code>
登入後複製

這表示任何基底類別的任何物件都可以從GetValue方法傳回。當方法傳回更通用的類型並且可以安全地轉換為各種特定類型時,這很有用。

以上是程式設計中協變和逆變有什麼不同?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板