Abgesehen von den mechanischen Schwierigkeiten, auf die Sie beim Deklarieren der Signaturen stoßen, macht das Ziel wenig Sinn. Sie versuchen, eine kovariante Vergleichsfunktion einzurichten, die die gesamte Idee der Einrichtung einer Schnittstelle, die abgeleitete Klassen anpassen können, zunichte macht.
Wenn Sie eine Unterklasse SubClass
so definieren, dass ihre Instanzen nur mit anderen SubClass
Instanzen verglichen werden können , wie wird dann SubClass
der durch definierte Vertrag erfüllt MyClass
? Denken Sie daran MyClass
, dass es und alle daraus abgeleiteten Typen mit anderen MyClass
Instanzen verglichen werden können . Sie versuchen , denn das ist nicht wahr zu machen SubClass
, was bedeutet , dass SubClass
nicht nicht erfüllt MyClass
ist Vertrag: Sie können nicht ersetzen , SubClass
für MyClass
, weilSubClass
's Anforderungen strenger sind.
Dieses Problem konzentriert sich auf Kovarianz und Kontravarianz und darauf, wie sich Funktionssignaturen durch Typableitung ändern können. Sie können sich entspannen eine Anforderung auf ein Argument der Typ Annahme einer breiteren Typ als die Supertyp Unterschrift Anforderungen-und Sie können stärken eine Anforderung auf einem Rückgabetyp versprechende eine schmalere Typ zurückzukehren als die Supertyp Unterschrift. Jede dieser Freiheiten erlaubt immer noch eine perfekte Substitution des abgeleiteten Typs für den Supertyp; Ein Anrufer kann den Unterschied nicht erkennen, wenn er den abgeleiteten Typ über die Schnittstelle des Supertyps verwendet, aber ein Anrufer, der den abgeleiteten Typ konkret verwendet, kann diese Freiheiten nutzen.
Willis Antwort lehrt etwas über generische Deklarationen, aber ich fordere Sie auf, Ihr Ziel zu überdenken, bevor Sie die Technik auf Kosten der Semantik akzeptieren.