Scala:具有特征的类,其构造函数接受另一个具有平行特征集的类?
假设我有一个a类,有一组混合特征,B类的值为a类。B类有没有办法拥有一组混合特征,要求a依次拥有某些特征(包括继承自多个其他此类特征的延伸B的特征) 例如:Scala:具有特征的类,其构造函数接受另一个具有平行特征集的类?,scala,class,constructor,multiple-inheritance,traits,Scala,Class,Constructor,Multiple Inheritance,Traits,假设我有一个a类,有一组混合特征,B类的值为a类。B类有没有办法拥有一组混合特征,要求a依次拥有某些特征(包括继承自多个其他此类特征的延伸B的特征) 例如: trait A trait Ax extends A trait Ay extends A class B(val a: A) // Should be traits, class Bx(ax: Ax) extends B(ax) // but traits can't class By(ay: Ay) ex
trait A
trait Ax extends A
trait Ay extends A
class B(val a: A) // Should be traits,
class Bx(ax: Ax) extends B(ax) // but traits can't
class By(ay: Ay) extends B(ay) // take parameters
class Bxy extends Bx with By // Can't mix in classes
有没有办法让Bxy既继承自Bx,又继承自Bx,并且需要一个具有特征Ax和Ay的值a
编辑——下面是一个可能更清楚的备选(仍然不起作用)示例:
class A
trait Ax extends A { def doAx: String = "Ax method" }
trait Ay extends A { def doAy: String = "Ay method" }
class B(val a: A)
trait Bx extends B {
require(a.isInstanceOf[Ax])
def doBx: String = a.doAx // Ax methods not actually accessible here
}
trait By extends B {
require(a.isInstanceOf[Ay])
def doBy: String = a.doAy // Nor Ay methods here
}
class Bxy(a: A with Ax with Ay) extends B(a) with Bx with By {
def doBxy: String = a.doAx + a.doAy
}
我无法将代码放在注释中加以澄清,但鉴于以下情况,您希望
a
变量发生什么变化
trait A
trait Ax extends A
trait Ay extends A
trait B {
val a: A
}
trait Bx extends B {
val x: Ax
}
trait By extends B {
val y: Ay
}
class Bxy(ax: Ax, ay: Ay) extends Bx with By {
val a = ??? // what do you want `a` to become here?
val x = ax
val y = ay
}
用不同类型覆盖a
然后:
不可能,因为
ay
不是Ax
。同样地,val a=ax
也不可能,因为ax
不是Ay
您可以将B
作为一个特征、抽象类,或采用通用的a
。下面是一个例子,其中B
是一个特征:
class A
trait Ax extends A { def doAx: String = "Ax method" }
trait Ay extends A { def doAy: String = "Ay method" }
trait B {
val a: A
}
trait Bx extends B {
val a: Ax
def doBx: String = a.doAx
}
trait By extends B {
val a: Ay
def doBy: String = a.doAy
}
class Bxy(val a: Ax with Ay) extends Bx with By {
def doBxy: String = a.doAx + a.doAy
}
您可以使用
apply
方法使用traits和伴随对象来模拟这一点
trait A
trait Ax extends A { def doAx = "Ax method" }
trait Ay extends A { def doAy = "Ay method" }
trait B {
val a: A
}
object B {
def apply(aa: A): B = new B {
val a = aa
}
}
trait Bx extends B {
val a: Ax
def doBx = a.doAx
}
object Bx {
def apply(ax: Ax): B = new Bx {
val a: Ax = ax
}
}
trait By extends B {
val a: Ay
def doBy = a.doAy
}
object By {
def apply(ay: Ay): B = new B {
val a: Ay = ay
}
}
class Bxy(val a: Ax with Ay) extends Bx with By {
def doBxy = a.doAx + a.doAy
}
同伴对象B
、Bx
和By
将作为其同伴特征的工厂,匿名创建它们
val a = new A {}
val ax = new Ax {}
val ay = new Ay {}
val axy = new Ax with Ay {}
scala> B(a)
res0: B = B$$anon$2@62f4ad6f
scala> Bx(ax)
res1: B = Bx$$anon$1@1436dd6f
scala> By(ay)
res2: B = By$$anon$3@6e84ee94
scala> new Bxy(axy)
res5: Bxy = Bxy@480101a7
scala> res5.doBxy
res6: String = Ax methodAy method
为什么需要它?如果要向B添加需要其A实例依次具有特定功能的功能,Bxy仍然只接受一个参数,并且只保留一个A值。我不想在A的Ax和Ay版本之间进行选择,我想要求A同时具有这两个特征。Bx和By不会向类添加值——只是向传递给类B构造函数的单个参数添加限制。(我添加了另一个示例来澄清这一点。)Bx和By的目的不是向B添加新的A值,而是限制原始A值的类型。请参阅答案的第二部分,其中我解释了为什么不可能。但我不想要
类Bxy(ax:ax,ay:ay)
,我想要类Bxy(axy:ax带ay)
--哪个应该与Bx和By一起使用,因为axy既是Ax又是Ay。Ax和Ay的类型是什么?A=水果,Ax=香蕉,Ay=橙色,我们如何将“香蕉和橙色”组合成一个东西?
trait A
trait Ax extends A { def doAx = "Ax method" }
trait Ay extends A { def doAy = "Ay method" }
trait B {
val a: A
}
object B {
def apply(aa: A): B = new B {
val a = aa
}
}
trait Bx extends B {
val a: Ax
def doBx = a.doAx
}
object Bx {
def apply(ax: Ax): B = new Bx {
val a: Ax = ax
}
}
trait By extends B {
val a: Ay
def doBy = a.doAy
}
object By {
def apply(ay: Ay): B = new B {
val a: Ay = ay
}
}
class Bxy(val a: Ax with Ay) extends Bx with By {
def doBxy = a.doAx + a.doAy
}
val a = new A {}
val ax = new Ax {}
val ay = new Ay {}
val axy = new Ax with Ay {}
scala> B(a)
res0: B = B$$anon$2@62f4ad6f
scala> Bx(ax)
res1: B = Bx$$anon$1@1436dd6f
scala> By(ay)
res2: B = By$$anon$3@6e84ee94
scala> new Bxy(axy)
res5: Bxy = Bxy@480101a7
scala> res5.doBxy
res6: String = Ax methodAy method