我想以不同的方式检查如何扩展此代码,然后在需要时将这些功能扩展混合在一起.
// Initial object algebra interface for expressions: integers and addition
trait ExpAlg[E] {
def lit(x : Int) : E
def add(e1 : E, e2 : E) : E
}
// An object algebra implementing that interface (evaluation)
// The evaluation interface
trait Eval {
def eval() : Int
}
// The object algebra
trait EvalExpAlg extends ExpAlg[Eval] {
def lit(x : Int) = new Eval() {
def eval() = x
}
def add(e1 : Eval, e2 : Eval) = new Eval() {
def eval() = e1.eval() + e2.eval()
}
}
// Evolution 1: Adding subtraction
trait SubExpAlg[E] extends ExpAlg[E] {
def sub(e1 : E, e2 : E) : E
}
// Updating evaluation:
trait EvalSubExpAlg extends EvalExpAlg with SubExpAlg[Eval] {
def sub(e1 : Eval, e2 : Eval) = new Eval() {
def eval() = e1.eval() - e2.eval()
}
}
// Evolution 2: Adding pretty printing
trait PPrint {
def print() : String
}
trait PrintExpAlg extends ExpAlg[PPrint] {
def lit(x: Int) = new PPrint() {
def print() = x.toString()
}
def add(e1: PPrint, e2: PPrint) = new PPrint() {
def print() = e1.print() + "+" + e2.print()
}
}
trait PrintSubExpAlg extends PrintExpAlg with SubExpAlg[PPrint] {
def sub(e1: PPrint, e2: PPrint) = new PPrint() {
def print() = e1.print() + "-" + e2.print()
}
}
object OA extends App {
trait Test extends EvalSubExpAlg with PrintSubExpAlg //error
}
Run Code Online (Sandbox Code Playgroud)
目前我收到的错误是:"非法继承;特征测试继承了特征SubExpAlg的不同类型实例:pack.SubExpAlg [pack.PPrint]和pack.SubExpAlg [pack.Eval]"
我怎么能把两个类型的Eval和PPint放在一个"帽子"下才被认为是来自同一个家族的类型,或者不是一个正确的解决方案,而我可能在两种类型的成员之间存在冲突的继承呢?
我改变了它,如下所示:class Operations
// Initial object algebra interface for expressions: integers and addition
trait ExpAlg {
type Opr <: Operations
def lit(x : Int) : Opr
def add(e1 : Opr, e2 : Opr) : Opr
}
// An object algebra implementing that interface (evaluation)
// The evaluation interface
trait Eval extends Operations {
def eval() : Int
}
// The object algebra
trait EvalExpAlg extends ExpAlg {
type Opr = Eval
def lit(x : Int) = new Eval() {
def eval() = x
}
def add(e1 : Eval, e2 : Eval) = new Eval() {
def eval() = e1.eval() + e2.eval()
}
}
// Evolution 1: Adding subtraction
trait SubExpAlg extends ExpAlg {
def sub(e1 : Opr, e2 : Opr) : Opr
}
// Updating evaluation:
trait EvalSubExpAlg extends EvalExpAlg with SubExpAlg {
def sub(e1 : Eval, e2 : Eval) = new Eval() {
def eval() = e1.eval() - e2.eval()
}
}
// Evolution 2: Adding pretty printing
trait PPrint extends Operations {
def print() : String
}
trait PrintExpAlg extends ExpAlg {
type Opr = PPrint
def lit(x: Int) = new PPrint() {
def print() = x.toString()
}
def add(e1: PPrint, e2: PPrint) = new PPrint() {
def print() = e1.print() + "+" + e2.print()
}
}
trait PrintSubExpAlg extends PrintExpAlg with SubExpAlg {
def sub(e1: PPrint, e2: PPrint) = new PPrint() {
def print() = e1.print() + "-" + e2.print()
}
}
object OA extends App {
class Test extends EvalSubExpAlg
class Test2 extends PrintSubExpAlg
val evaluate = new Test
val print = new Test2
val l1 = evaluate.lit(5)
val l2 = evaluate.lit(4)
val add1 = evaluate.add(l1, l2).eval()
val print1 = print.add(print.lit(5), print.lit(4)).print()
println(print1)
println(add1)
}
Run Code Online (Sandbox Code Playgroud)
我唯一要问的可能是只使用一个Test类并在两种类型的方法之间导航(通过引用这些类型).
让我们简化它:
trait Z {val a = 5}
trait K {val a = 6}
trait A[T] { def aa: T}
trait A1 extends A[Z] { def aa = new Z{}}
trait A2 extends A[K] { def aa = new K{}}
scala> class C extends A1 with A2
<console>:12: error: illegal inheritance;
class C inherits different type instances of trait A:
A[K] and A[Z]
Run Code Online (Sandbox Code Playgroud)
那么,当你这么做时,你期望被称为什么(new C).aa?如果你真的不在乎,只想访问里面的那些C:
trait A {type T; protected def aa: T}
trait A1 extends A {type T >: Z; protected def aa = new Z{}}
trait A2 extends A {type T >: K; protected def aa = new K{}}
scala> class C extends A1 with A2 {
override type T = Any
override protected def aa = ???
def bbb:Z = super[A1].aa
def zzz:K = super[A2].aa
}
Run Code Online (Sandbox Code Playgroud)
但我会建议选择一些默认的方法和继承Z从K或K从Z提供正常的默认实现C#aa.一般来说,这里的问题是scala中的特征既适用于mixin又适用于多态,因此你不能只关闭外部世界的成员(由于Liskov-Substitution),即使你实际上并不需要自动强制转换为超类型.有关详情,请参阅相关问题
| 归档时间: |
|
| 查看次数: |
606 次 |
| 最近记录: |