我试图编写一些抽象代码,使其逐步变得更加复杂。它在其中一个步骤中打破了。
第1步,正确
trait Base
trait C1 extends Base
trait Abst extends Base
trait Conc extends Abst with C1
第二步,正确
object BaseHolder {
trait Data
}
object C1Holder {
trait Data extends BaseHolder.Data
}
trait Abst extends BaseHolder.Data
trait Conc extends Abst with C1Holder.Data
第3步,错误错误
trait BaseHolder {
trait Data
}
object BaseHolder extends BaseHolder
trait C1Holder extends BaseHolder {
trait Data extends super.Data
}
object C1Holder extends C1Holder
trait Abst extends BaseHolder.Data
trait Conc extends Abst with C1Holder.Data
我有错误: 非法继承; trait Con继承了特征数据的不同类型实例
这个错误意味着什么,有没有办法绕过它?
答案 0 :(得分:6)
完整的错误消息是
[error] trait Conc inherits different type instances of trait Data:
[error] C1Holder.Data and BaseHolder.Data
[error] trait Conc extends Abst with C1Holder.Data
[error] ^
[error] one error found
它说(object BaseHolder).Data
与(object C1Holder).Data
不一致,因为虽然后者符合(trait BaseHolder)#Data
,但这不像单身实例trait Data
中的object BaseHolder
那么具体}。
修改的。请注意,类型和值存在于不同的名称空间中,因此单独使用名称BaseHolder
是不明确的,它可以引用对象的特征。但是,当提到一个类型时,“。”或“#”符号消除歧义:
T#Data
始终表示类型 Data
中的T
类型成员。例如,BaseHolder#Data
将引用特征BaseHolder
。
x.Data
始终表示对象 Data
中的x
类型成员。例如,BaseHolder.Data
将引用单身对象BaseHolder
。
请注意,x
的两个y
和trait BaseHolder
个实例将具有不同的类型x.Data
和y.Data
;这是路径依赖类型的工作方式。另请注意,object BaseHolder extends BaseHolder
只是trait BaseHolder
的一个特定实例。
要让您的代码进行编译,请确保(trait C1Holder)#Data
实际符合(object BaseHolder).Data
trait BaseHolder {
trait Data
}
object BaseHolder extends BaseHolder
trait C1Holder extends BaseHolder {
trait Data extends BaseHolder.Data // Here BaseHolder refers to singleton object
}
object C1Holder extends C1Holder
trait Abst extends BaseHolder.Data
trait Conc extends Abst with C1Holder.Data
在这个例子中,特征没有做太多,所以你可能只想使用
object BaseHolder {
trait Data
}
object C1Holder {
trait Data extends BaseHolder.Data
}
trait Abst extends BaseHolder.Data
trait Conc extends Abst with C1Holder.Data
答案 1 :(得分:2)
您将外部特征视为内在特征的简单容器,几乎就像处理包装一样。然而,内部类和特征与其父类之间的关系更为复杂。
内部类和特征始终与父类的实例相关联。没有父实例就无法创建内部类。实际上,内部类有一个隐藏引用,指向父类的实例。
在您的情况下,特征数据与对象BaseHolder相关联。然后特征Abst扩展了BaseHolder.Data,因此它也与对象BaseHolder相关联。这意味着Abst将引用BaseHolder对象作为其父对象。
另一方面,C1Holder.Data引用C1Holder作为其父级。因此,当您定义Conc时,它必须引用BaseHolder和C1Holder作为父级。但内在特征只能有一个父母。因此错误。