scala中trait和abstract class在隐式转换中的区别

说半天还不如看一点代码更清楚问题之所在:ide

object ImplicitObject3 {
def main(args: Array[String]): Unit = {
    def sum[A](xs:List[A])(implicit st:SubTemplate[A]):A = {
      if(xs.isEmpty) st.unit
      else st.add(xs.head,sum(xs.tail))
    }
    
    implicit object SubTemplateImplicitIntValue extends SubTemplate[Int] {
      override def unit: Int = 0

      override def add(x: Int, y: Int): Int = x + y
    }
    implicit object SubTemplateImplicitStringVlaue extends SubTemplate[String] {
      override def unit: String = ""

      override def add(x: String, y: String): String = x + y
    }
    println(sum(List(1,2,3,4,5)))
    println(sum(List("abc","efg","hijk")))
  }
}
trait Template[A] {
  def add(x:A,y:A):A
}
trait SubTemplate[A] extends Template[A] {
  def unit:A
}

编译正确,执行时:在类加载器加载时出现异常。可是将二个trait放在object ImplicitObject3中,无论是放在main的前面仍是后面都执行OK:scala

object ImplicitObject3 {
trait Template[A] {
  def add(x:A,y:A):A
}
trait SubTemplate[A] extends Template[A] {
  def unit:A
}
def main(args: Array[String]): Unit = {
    def sum[A](xs:List[A])(implicit st:SubTemplate[A]):A = {
      if(xs.isEmpty) st.unit
      else st.add(xs.head,sum(xs.tail))
    }
    
    implicit object SubTemplateImplicitIntValue extends SubTemplate[Int] {
      override def unit: Int = 0

      override def add(x: Int, y: Int): Int = x + y
    }
    implicit object SubTemplateImplicitStringVlaue extends SubTemplate[String] {
      override def unit: String = ""

      override def add(x: String, y: String): String = x + y
    }
    println(sum(List(1,2,3,4,5)))
    println(sum(List("abc","efg","hijk")))
  }
}

若是将二个trait改成abstract class形式,定义在object ImplicitObject3以外执行也OK:调试

object ImplicitObject3 {
def main(args: Array[String]): Unit = {
    def sum[A](xs:List[A])(implicit st:SubTemplate[A]):A = {
      if(xs.isEmpty) st.unit
      else st.add(xs.head,sum(xs.tail))
    }
    
    implicit object SubTemplateImplicitIntValue extends SubTemplate[Int] {
      override def unit: Int = 0

      override def add(x: Int, y: Int): Int = x + y
    }
    implicit object SubTemplateImplicitStringVlaue extends SubTemplate[String] {
      override def unit: String = ""

      override def add(x: String, y: String): String = x + y
    }
    println(sum(List(1,2,3,4,5)))
    println(sum(List("abc","efg","hijk")))
  }
}
abstract class Template[A] {
  def add(x:A,y:A):A
}
abstract class SubTemplate[A] extends Template[A] {
  def unit:A
}

为何会有这样的现象,缘由是什么呢???????????????????????code

当我在object ImplicitObject3外面定义二个trait以外,还在二个trait同级定义了一个继承自SubTemplate[A]的abstract class类,同时将main中二个implicit object继承的父改成这个抽象类,则一切都OK了。这种状况下,实验OK,其实缘由好理解:继承

object ImplicitObject3 {
def main(args: Array[String]): Unit = {
    def sum[A](xs:List[A])(implicit st:SubTemplate[A]):A = {
      if(xs.isEmpty) st.unit
      else st.add(xs.head,sum(xs.tail))
    }
    
    implicit object SubTemplateImplicitIntValue extends abstractTemplate[Int] {
      override def unit: Int = 0

      override def add(x: Int, y: Int): Int = x + y
    }
    implicit object SubTemplateImplicitStringVlaue extends abstractTemplate[String] {
      override def unit: String = ""

      override def add(x: String, y: String): String = x + y
    }
    println(sum(List(1,2,3,4,5)))
    println(sum(List("abc","efg","hijk")))
  }
}
trait Template[A] {
  def add(x:A,y:A):A
}
trait SubTemplate[A] extends Template[A] {
  def unit:A
}
abstract class abstractTemplate[A] extends SubTemplate[A]

有一次无心中,我将二个trait放在另外一个单独的scala文件中,而后我编译工程而后调试,不成功。鬼使神差地在main的最开头import SubTemplate一次,竟然成功了。我将磁盘上全部class文件都删除了再编译工程却又不成功。而后再去掉import,单独编译那个scala文件,再编译工程却又成功执行代码了。总结来看:这是因为IDEA形成class文件与源代码不一致的缘由ci