需要澄清Scala方差和类型边界

时间:2012-03-05 16:02:42

标签: scala variance type-bounds

我的scala特征定义如下:

trait AdvertisementDAO[A <: Advertisement] extends CrudRepository[A, Integer] {
...

我希望能够获得这个DAO的实例,它可以用于广告的子类或基础广告类本身。我不确定如何达到预期的效果。

以下是我的尝试:

@Inject
var advertisementDAO: AdvertisementDAO[+Advertisement] = _

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:3)

看起来您正在尝试将特征的类型参数A定义为广告DAO,作为协变。下面是使用协方差注释+。

的上一个答案的代码示例的变体
trait Advertisement {}

class AdvertisementImpl extends Advertisement{}

class CrudRepository[+A,B]  {}

trait AdvertisementDAO[+A <: Advertisement] extends CrudRepository[A, Integer] {}

class AdvertisementDAOImpl[+A <: Advertisement] extends AdvertisementDAO[A]{}

class AdvertisementDAOImpl2 extends AdvertisementDAO[AdvertisementImpl]{}

class AdvertisementDAOImpl3 extends AdvertisementDAO[Advertisement]{}

object Tester
{
  def main(args:Array[String]):Unit =
  {
    var advertisementDAO: AdvertisementDAO[Advertisement] = null
    advertisementDAO = new AdvertisementDAOImpl
    advertisementDAO = new AdvertisementDAOImpl2 
    advertisementDAO = new AdvertisementDAOImpl3
  }
}

协变泛型的另一个例子是scala.collection.immutable.List。将泛型(类或特征)C定义为协变意味着C [S]是C [T]的子类型,如果类型S是类型T的子类型。例如,AdvertisementDAO [AdvertisementImpl]是AdvertisementDAO的子类型[Advertisement] ]因为AdvertisementImpl是子类型Advertisement(因为AdvertisementImpl扩展了Advertisement)。我发布了一个paper,其中包含许多语言中出现的差异教程(例如Scala,C#,Java)。 Slides也可用于快速浏览。希望这会有所帮助。

答案 1 :(得分:2)

我尝试了很多组合,但是收到了一个用scala 2.9.1编译的组合

  var advertisementDAO: AdvertisementDAO[_ <:Advertisement] = _

  advertisementDAO = new AdvertisementDAOImpl

  advertisementDAO = new AdvertisementDAOImpl2 

  advertisementDAO = new AdvertisementDAOImpl3

我的代码:

trait Advertisement {}

class AdvertisementImpl extends Advertisement{}

class CrudRepository[A,B]  {}

trait AdvertisementDAO[ A <: Advertisement] extends CrudRepository[A, Integer] {}

class AdvertisementDAOImpl[A <: Advertisement] extends AdvertisementDAO[A]{}

class AdvertisementDAOImpl2 extends AdvertisementDAO[AdvertisementImpl]{}

class AdvertisementDAOImpl3 extends AdvertisementDAO[Advertisement]{}