Scala类型不适用于抽象类,但适用于特征

时间:2017-02-02 19:03:10

标签: scala abstract-class traits implicit type-bounds

我正在尝试扩展泛型mSort函数以使用implicits和类型边界。当我使用通用特征扩展Ordered而不是抽象类时,它工作正常。能帮忙吗?

object MergeSort extends App {

  // With Abstract Class
  abstract class Id(id: Int) extends Ordered[Id] {
    override def compare(that: Id): Int = this.id.compareTo(that.id)
  }
  case class Emp(id: Int, name: String) extends Id(id) {
    //override def compare(that: Emp): Int = this.name.compareTo(that.name)
  }

//// With Traits: Works fine
//  trait Id extends Ordered[Id]{
//    val id: Int
//    override def compare(that: Id): Int = this.id.compareTo(that.id)
//  }
//  case class Emp(id: Int, name: String) extends Id {
//    //override def compare(that: Emp): Int = this.name.compareTo(that.name)
//  }


  object MSort {
    def msort[T <% Ordered[T]](list: List[T])(implicit less: (T, T) => Boolean): List[T] = {
      def merge(xs: List[T], ys: List[T]): List[T] = {
    (xs, ys) match {
      case (Nil, _) => ys
      case (_, Nil) => xs
      case (x :: xs1, y :: ys1) => if (less(x, y)) x :: merge(xs1, ys) else y :: merge(xs, ys1)
    }
      }
      val n = list.length/2
      if(n==0) list
      else {
    val (ys, zs) = list.splitAt(n)
    merge(msort(ys), msort(zs))
      }
    }
  }

  implicit def less [T <% Ordered[T]] (x: T, y: T): Boolean = x <= y
//  MSort.msort[Int](List(6, 3, 9, 1)).foreach(println)
//  MSort.msort[Char](List('a', 'z', 'Z', 'D')).foreach(println)
//  MSort.msort[String](List("appolo", "lunar", "Zapplin", "Kafka")).foreach(println)
//  MSort.msort[Double](List(12.3, 14, 19.3, -32.443)).foreach(println)
  MSort.msort[Id](List(Emp(7, "appolo"), Emp(2, "lunar"), Emp(9, "Zapplin"), Emp(1, "Kafka"))).foreach(println)

}

错误:

Error:(5, 66) value id is not a member of MergeSort.Id
override def compare(that: Id): Int = this.id.compareTo(that.id)

1 个答案:

答案 0 :(得分:4)

没有&#34; val&#34; id只是一个构造函数arg,而不是该类的属性。

abstract class Id(id: Int) extends Ordered[Id] {
  override def compare(that: Id): Int = this.id.compareTo(that.id)
}

这也意味着你的Emp中的id参数需要被标记为覆盖

case class Emp(override val id: Int, name: String) extends Id(id) {
  //override def compare(that: Emp): Int = this.name.compareTo(that.name)
}