为何签名不同的方法会报“ambiguous reference to overloaded definition”错误?
问题解析:为什么调用
B.text会触发报错? 嘿,这个问题其实是Scala方法解析规则的一个典型坑点,我来给你掰扯清楚:
你写的代码里,case object B中的text(s: Seq[String])并没有覆盖父trait A的无参text方法——它只是在B中重载了一个同名但参数不同的方法。但Scala的名称解析逻辑是这样的:
当你调用B.text时,编译器会先在B自己的成员里找名为text的方法。它确实找到了那个带Seq[String]参数的版本,然后就会尝试把你的无参调用和这个方法的签名匹配,结果发现参数数量不匹配,直接就抛出错误了——根本不会再去父trait A里找那个无参的text方法。
简单说就是:Scala在解析方法调用时,优先匹配当前类/对象中定义的同名方法,参数不匹配就报错,不会自动 fallback到父类的同名方法。
解决办法有两个:
显式继承父类的无参方法:在B中明确重写(或者说继承)父类的无参
text,让编译器知道B有两个重载的text方法:trait A { def text: String = "abc" } case object B extends A { def text(s: Seq[String]): String = s.mkString // 显式继承父类的无参方法 override def text: String = super.text }这样再调用
B.text就会匹配无参版本,调用B.text(Seq("a","b"))就会匹配带参数的版本。给带参数的方法换个名字:如果没必要用同名方法,直接把B中的方法改名为
textJoin或者其他名称,彻底避免名称冲突:trait A { def text: String = "abc" } case object B extends A { def textJoin(s: Seq[String]): String = s.mkString }这样
B.text自然就会调用A中的无参方法了。
内容的提问来源于stack exchange,提问作者borice
相关产品推荐
相关产品推荐

