【发布时间】:2015-02-05 16:23:23
【问题描述】:
Scala 中的特征可以用作混合和接口。这会导致一些不一致 - 如果我想关闭 trait 中的某些方法,我不能这样做:
object Library {
protected trait A { def a: Int = 5 }
trait B extends A { private override def a: Int = super.a }
//I want to close `a` memeber for all traits extending B; it's still possible to open it in some another trait `C extends A`, or even `Z extends B with C`
}
// Exiting paste mode, now interpreting.
<console>:10: error: overriding method a in trait A of type => Int;
method a has weaker access privileges; it should not be private
trait B extends A { private override def a: Int = super.a }
^
从LSP 的角度来看,这样的错误完全没问题,因为我(或编译器)可能希望将其转换为超类型A。但如果我只是将它用作混音,我实际上不需要这样做,例如在一些蛋糕图案的变化中。我会做类似的事情:
import Library._
object O extends B with K with L with App
就是这样。我什至无法在这里访问 trait A。我知道,有类型推断可能会上升到超类型,但它只是一个“类型行”,所以编译器可以在这里跳过A 并继续(当然这是非常理论上的)。另一个例子 - here 我必须为方法提供默认实现,而我并不真正需要。
我当前使用的解决方案是 OOP 组合,但它不是那么灵活(因为线性化在这里不起作用)并且与混入概念不太兼容。我见过的一些项目,他们实际上做了混合,并且有“超过 9000 个”冗余和可见的成员。几年前,有一个想法是通过指定的with 关键字而不是extends 来“标记”此类mixins 组合,但现在甚至找不到该线程。
那么,对于 ad-hoc 成员封装有什么更好的做法吗?
【问题讨论】:
标签: scala encapsulation mixins traits