Я новичок в scala. Я пытаюсь выяснить, как работают все отношения контравариантности. Я понимаю концепцию ковариации и инварианта, и я также знаю, как я буду реализовывать их на практике. Я также понимаю концепцию контравариантности (противоположность ковариации) и то, как она реализуется в признаке Function1 в Scala. Это дает абстракцию, не переопределяя реализации Function1 для разных классов. Но, я все еще не понимаю это, странно? Теперь, я почти там ... как я могу решить следующую проблему с контрвариации:Контравариантность в scala
class GarbageCan[-A] {
def doSomething(a: A): Unit ={
// do something with 'a' of subtype that is not possible with the supertype
}
}
def setGarbageCanForPlastic(gc: GarbageCan[PlasticItem]): Unit = {
}
В приведенном выше примере извлекается из http://blog.kamkor.me/Covariance-And-Contravariance-In-Scala/. Действительно хорошее объяснение по этому вопросу. Иерархия выглядит следующим образом: Элемент (базовый класс) -> PlasticItem (подкласс) -> PlasticBottle (подкласс подкласса)
Функция setGarbageCanForPlastic принимает GarbageCan с типом PlasticItem. Поскольку параметризованные типа контравариантен, следующее утверждение вполне законно:
setGarbageCanForPlastic(new GarbageCan[Item])
Теперь функция йоЗотеЬЫпд принимает параметр типа, который контравариантен. Как я могу работать с этим типом, если я не знаю, является ли тип базовым классом «Item» или подклассом «PlasticItem»? Я могу сделать что-то, что допустимо в подклассе, а не в базовом классе. Если бы это был ковариантный параметр, это не проблема, подкласс наследует все от базового класса.
Я потерял это право? ... Надеюсь, кто-то может мне помочь.
Почему вас беспокоит только 'GarbageCan [Item]'? Что мешает кому-то создать «GrabageCan [Option [List [Int]]]? Например? Игнорируйте дисперсию контравариантности на мгновение. Даже если это было просто «GrabageCan [A]», как вы думаете, что ваш 'doSomething' будет работать? – Dima
Хороший вопрос ... Его следует использовать только как «тип» внутри тела? –
Ну, я не уверен, что вы подразумеваете под «этим», и о чьем «теле», о котором вы говорите, поэтому я не знаю :) Суть в том, что вы _first_ придумали фактический прецедент, а _then_ см., если для этого подходит контравариантность/ковариация/инвариантность, а не наоборот. – Dima