Scala - 上限实例的调用方法

时间:2016-12-15 15:53:31

标签: scala oop generics types scala-generics

在下面的代码中,有一个DogSearcher,它有一个名为fetch的方法,需要一个Ball。我们还可能有一个CatSearcher,其中包含一个预期响铃的fetch方法。我们的想法是,我们可以在从PetSearcher继承的实例上调用fetch,并为其提供不同的参数。

知道我错过了什么吗?

trait PetSearcher {
  def search(what: Thing): Unit = {
    println("default searching")
  }
}

class DogSearcher extends PetSearcher {
  def search(what: Ball): Unit = {
    println("dog searching")
  }
}
trait Thing {
  val name: String
}
case class Ball(name: String) extends Thing

class Pet {
  def fetch[S <: PetSearcher, F <: Thing](searcher: S, what: F): Unit = {
    println(what)
    searcher.search(what)
  }
}

class Dog extends Pet {
  val searcher = new DogSearcher()
  val ball = new Ball("red")
  def go(): Unit = {
    fetch[DogSearcher, Ball](searcher, ball)
  }
}

//should use DogSearcher but calls fetch on Search, not on DogSearcher. 
// So prints default searching, not dog searching..
new Dog().go() 

2 个答案:

答案 0 :(得分:2)

DogSearch的{​​{1}}方法不会覆盖PetSearcher的search方法,因为参数类型不同(search是PetSearcher的what但是{{1}对于DogSearcher - Thing扩展Ball的事实不足以使函数调用相同的事实。)

Ball使用类型参数来定义Thing的类型,然后PetSearcher可以覆盖此项(请注意what关键字是必要的):

DogSearcher

要使其编译,您还需要通过将类型参数F(此Pet搜索的Thing的子类型)添加到PetSearcher来更新Pet中PetSearcher的使用:

override

答案 1 :(得分:2)

作为@JamesThorniley's answer的替代方案,您可以定义search以接受任何扩展Thing的内容:

trait PetSearcher {
    def search[T <: Thing](what: T): Unit = {
        println("default searching")
    }
}

class  DogSearcher extends PetSearcher {
    override def search[T <: Thing](what: T): Unit = {
        println("dog searching")
    }
}

根据需要输出dog searching