2012-11-17 93 views
0

我剛剛在我的編程語言課上學到「逆變參數類型實際上是安全的,但它們沒有被發現有用,因此在實際語言中不被支持。」即使他們不支持,我很困惑,爲什麼這樣的例子中,我們分別給予仍然是,從理論上講,「安全」:爲什麼這些逆變參數類型被認爲是安全的?

class Animal { 
    ... 
    public bool compare(Panda) { ... } 
} 

class Panda extends Animal { 
    ... 
    public bool compare(Animal) { ... } 
} 

據我瞭解,與子類型的問題上來,當東西這樣做會導致特異性的喪失。那麼,如果我這樣做呢? :

Panda p = new Panda(); 
Animal a = new Animal 
... 
p.compare(a); 

當我看着這個,看起來像熊貓可能(可能確實)有一些額外的領域,普通的動物不知道。因此,即使他們所有的動物特定數據成員都是相同的,熊貓也可以有其他不同的東西。如何將它與一個普通的動物相比較呢?它會只考慮動物的東西,而忽略其餘的東西嗎?

回答

2

在您的示例中,您不使用任何generic類型。你有Panda延伸Animal,這是一個inheritance的例子,並導致polymorphism這是或多或少你所描述的。檢查鏈接。

要獲得反轉效果,您需要考慮一些通用類型。我將以.NET類型IComparer`1[T]爲例。用C#語法(這我會用,而不是Java),我們表明,IComparer逆變T由定義寫in

public interface IComparer<in T> 
{ 
    ... 
} 

假設我有一個返回IComparer`1[Animal](或IComaparer<Animal>的方法),如:

static IComparer<Animal> CreateAnimalComparer() 
{ 
    // code that returns something here 
} 

現在在C#中,這是法理上的說法:

IComparer<Panda> myPandaComparer = CreateAnimalComparer(); 

現在,這個是因爲變相。請注意,類型IComparer<Animal>不是源自(或「擴展」)IComparer<Panda>類型。相反,Panda來自Animal,這導致IComparer<Xxxx>可以相互賦值(以相反的順序,因此「逆變」(而不是「協方差」))。

聲明Comparer<>逆變是有意義的原因是,如果你有一個比較器可以比較兩個任意的動物,並返回一個有符號的數字來表明哪個更大,那麼同一個比較器也可以取兩個熊貓並比較那些。熊貓是動物。

所以關係

任何PandaAnimal

(從繼承)導致關係

任何IComparer<Animal>IComparer<Panda>

(通過反轉)。

對於協方差,相同的關係

任何Panda一個例子是一個Animal

導致

任何IEnumerable<Panda>被一個IEnumerable<Animal>

by covariance(IEnumerable<out T>)。

相關問題