Scala:Class 具有其构造函数采用另一个具有一组并行特征的 class 的特征?
Scala: Class with traits whose constructor takes another class with a parallel set of traits?
假设我有一个具有一组混合特征的 class A,以及一个值为 class A 的 class B。有没有办法 class 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) extends B(ay) // take parameters
class Bxy extends Bx with By // Can't mix in classes
有没有什么方法可以让 Bxy 既继承自 Bx 和 By,又需要具有 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
trait A
trait Ax extends A
trait Ay extends A
trait B {
val a: A
}
trait Bx extends B {
val a: Ax
}
trait By extends B {
val a: Ay
}
然后:
class Bxy(ax: Ax, ay: Ay) extends Bx with By {
val a = ay
}
不可能,因为 ay
不是 Ax
。同样,val a = ax
是不可能的,因为 ax
不是 Ay
.
您可以使 B
成为特征,抽象 class,或采用通用 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
方法使用特征和伴随对象来模拟这一点。
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@62f4ad6f
scala> Bx(ax)
res1: B = Bx$$anon@1436dd6f
scala> By(ay)
res2: B = By$$anon@6e84ee94
scala> new Bxy(axy)
res5: Bxy = Bxy@480101a7
scala> res5.doBxy
res6: String = Ax methodAy method
假设我有一个具有一组混合特征的 class A,以及一个值为 class A 的 class B。有没有办法 class 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) extends B(ay) // take parameters
class Bxy extends Bx with By // Can't mix in classes
有没有什么方法可以让 Bxy 既继承自 Bx 和 By,又需要具有 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
trait A
trait Ax extends A
trait Ay extends A
trait B {
val a: A
}
trait Bx extends B {
val a: Ax
}
trait By extends B {
val a: Ay
}
然后:
class Bxy(ax: Ax, ay: Ay) extends Bx with By {
val a = ay
}
不可能,因为 ay
不是 Ax
。同样,val a = ax
是不可能的,因为 ax
不是 Ay
.
您可以使 B
成为特征,抽象 class,或采用通用 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
方法使用特征和伴随对象来模拟这一点。
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@62f4ad6f
scala> Bx(ax)
res1: B = Bx$$anon@1436dd6f
scala> By(ay)
res2: B = By$$anon@6e84ee94
scala> new Bxy(axy)
res5: Bxy = Bxy@480101a7
scala> res5.doBxy
res6: String = Ax methodAy method