假设我有一个基类
abstract class Base {
type B<: Base
def rep:String
def copy:B
}
class MyBase(override val rep:String) extends Base {
type B = MyBase
override def copy = new MyBase(rep)
}
Run Code Online (Sandbox Code Playgroud)
然后我尝试添加另一个特性作为mixin,我希望复制的返回类型是适当的类型(意味着在mixin上调用copy会返回mixin类型,通过将B设置为适当的类型).我无法编译,甚至无法理解override关键字的位置.
编辑:我已经改进了这个例子
abstract class Base {
type B <: Base
def rep:String
def copy:B
}
class MyBase(val rep:String) extends Base {
type B = MyBase
def copy = new MyBase(rep)
}
trait DecBase extends Base {
abstract override def rep = "Rep: "+super.rep
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,如何为DecBase声明一个合适的B类和复制方法,以便该副本返回一个DecBase,而且,为什么不编译?
println(((new MyBase("ofer") with DecBase)).rep)
Run Code Online (Sandbox Code Playgroud)
这是我在Java中可以实现的(带有一些肮脏,使用递归泛型类型).我确信在Scala中做一些更好的事情是可能的.
编辑
运用
trait DecBase extends Base {
override type B = DecBase
abstract override val rep= "Dec:"+super.rep
abstract override def copy = new MyBase(rep) with DecBase
}
Run Code Online (Sandbox Code Playgroud)
我得到以下编译器错误
error: overriding type B in class MyBase, which equals com.amadesa.scripts.MyBase;
type B in trait DecBase, which equals com.amadesa.scripts.DecBase has incompatible type
println(((new MyBase("ofer") with DecBase)).rep)
error: overriding type B in class MyBase, which equals com.amadesa.scripts.MyBase;
type B in trait DecBase, which equals com.amadesa.scripts.DecBase has incompatible type
abstract override def copy = new MyBase(rep) with DecBase
Run Code Online (Sandbox Code Playgroud)
我想你的混音看起来像这样
trait MixIn extends Base {
override B = MixinBase
override def copy = new MixinBase(rep)
}
Run Code Online (Sandbox Code Playgroud)
我认为overrideonMyBase是问题的一部分。这是不必要的并且会使编译器感到困惑。
如果copyonBase实际上有一个实现,那么有override必要的话,您需要告诉编译器要使用哪个方法。如果它对它来说不明显,它就会举手并提出错误。尝试这个。
val b = new MyBase(rep) with MixIn {
override def copy = MixIn.super.copy
}
Run Code Online (Sandbox Code Playgroud)
这MixIn.super.copy是打给您想要的人的电话。
您可能需要查看有关Scala 类线性化的此页面,以了解当类型中存在方法的竞争实现时会发生什么情况。
编辑:哦,这是一个完全不同的问题。这是 中的 val case MyBase(val rep:String)。您不能使用 def 覆盖 val,因为 val 被假定为不可变的。您可以用 val 覆盖 def 或 var,但反之则不行。做了:
trait DecBase extends Base {
abstract override val rep = "Rep: "+super.rep
}
Run Code Online (Sandbox Code Playgroud)
下次请包含编译器错误。它使您更容易看出问题所在。