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); 

私がこれを見ると、パンダは普通の動物が知らないであろういくつかの余分なフィールドをそこに持つことができた(そしておそらくそうしている)ようです。したがって、動物固有のデータメンバーがすべて同じであっても、パンダは他の異なるものを持つことができます。それはどうやってそれを普通の動物と比較しても大丈夫でしょうか?動物だけのものを考慮し、残りを無視するでしょうか?

4

1 に答える 1

2

あなたの例では、ジェネリック型を使用していません。あなたはPanda拡張を持っています、そしてそれは継承Animalの例であり、多かれ少なかれあなたが説明するものであるポリモーフィズムにつながります。リンクを確認してください。

共変性を得るには、いくつかのジェネリック型を考慮する必要があります。IComparer`1[T]例として.NETタイプを使用します。C#構文(Javaではなく使用します)を使用して、定義を記述することにより、それIComparer反変であることを示します。Tin

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<>は、2つの任意の動物を比較できる比較者がいて、どちらが大きいかを示す符号付きの数値を返す場合、同じ比較者が2つのパンダを取り込んでそれらを比較できるためです。パンダは動物です。

だから関係

いずれかPandaAnimal

(継承から)関係につながる

いずれかIComparer<Animal>IComparer<Panda>

(共変性による)。

共分散の例では、同じ関係

いずれかPandaAnimal

につながる

いずれかIEnumerable<Panda>IEnumerable<Animal>

共分散による(IEnumerable<out T>)。

于 2012-11-25T13:00:52.233 に答える