我是scala的新手。我试图弄清楚整个逆关系是如何工作的。我了解协方差和不变性的概念,并且我也知道如何实践地实现它们。
我还了解了逆方差(协方差的反向)的概念,以及如何在Scala的Function1特性中实现逆方差。它为您提供了一个抽象,而无需为不同的类重新定义Function1实现。但是,我还是不完全明白,奇怪吗?现在,我快到了……我该如何解决以下问题:
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函数接受类型为PlasticItem的GarbageCan。由于Parameterized类型是互变的,因此以下语句完全合法:
setGarbageCanForPlastic(new GarbageCan[Item])
现在,doSomething函数接受一个反型的Type参数。如果我不知道该类型是基类“ Item”还是子类“ PlasticItem”,该如何使用该类型?我可以做一些在子类中而不是在基类中允许的事情。如果这是一个协变量参数,那么这将是没有问题的,子类将从基类继承所有内容。
我输了吗?...希望有人能帮助我。
最佳答案
首先,由于doSomething
方法实际上不知道a
是什么,因此除了本质上丢弃A
之外,它实际上无能为力。为了使其更有用,您将需要像class GarbageCan[-A <: Item]
这样的绑定。
现在,假设setGarbageCanForPlastic(gc)
调用gc.doSomething(new PlasticItem)
。由于A
中的GarbageCan[A]
是互变的,因此我们有GarbageCan[Item] <: GarbageCan[PlasticItem] <: GarbageCan[PlasticBottle]
。实际上,函数setGarbageCanForPlastic(new GarbageCan[Item]))
是安全的,因为GarbageCan[Item]
的doSomething
可以处理包括Item
的任何PlasticItem
,而调用setGarbageCanForPlastic(new GarbageCan[PlasticBottle]))
是不安全的,因为GarbageCan[PlasticBottle]
的doSomething
可能不安全。能够采用不一定是PlasticItem
的PlasticBottle
。
关于scala - 标量的协方差,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38207310/