Scala中能否用case class实现带参数的trait方法?
解决Scala中用Case Class实现带参Trait方法的问题
这个报错的核心原因很明确:你在trait T里声明的g是一个方法签名,但在object O里定义的case class g是一个类——这完全不是一回事,编译器自然会认为你没有实现trait T要求的g方法。
要实现你的需求,你需要把case class和方法分开:先定义case class(最好换个名字避免冲突),然后在trait T的g方法实现里返回这个case class的实例。
正确实现示例
trait T[X] { def f: X; def g(x: X): X } trait XImpl { def sayHi: String } object O extends T[XImpl] { // 无参方法的case object实现和原来一致 case object f extends XImpl { val sayHi = "Hi" } // 定义case class,换个名字比如G,避免和方法g冲突 case class G(x: XImpl) extends XImpl { def sayHi = x.sayHi.toUpperCase } // 显式实现trait中的g方法,返回G的实例 override def g(x: XImpl): XImpl = G(x) }
为什么原来的写法不行?
在Scala中,def g(x: XImpl): XImpl是一个需要提供方法体的抽象方法,而case class g(...)只是定义了一个新的类类型,它不会自动成为方法g的实现。编译器只会把它当作一个和方法同名的类,完全不会关联到trait的方法要求上。
另一种简化写法(不需要单独定义case class)
如果你不需要case class带来的自动生成方法(比如equals、hashCode、toString),也可以直接在方法里返回匿名类:
object O extends T[XImpl] { case object f extends XImpl { val sayHi = "Hi" } override def g(x: XImpl): XImpl = new XImpl { def sayHi = x.sayHi.toUpperCase } }
但如果你确实需要case class的特性,那么第一种显式实现方法并返回case class实例的方式是必须的——你没法直接用case class替代方法的实现,必须在方法内部实例化它。
内容的提问来源于stack exchange,提问作者xavlours
相关产品推荐
相关产品推荐

