【发布时间】:2013-04-05 14:19:12
【问题描述】:
我碰巧发现里面不允许有抽象的私有字段 一个特质,也就是,
trait A1 {
//private val a: Int // Not allowed
protected val b: Int // OK
}
如果是私有字段,对抽象类做这样的事情似乎没问题 是构造函数参数,即
abstract class A2 (private val i: Int) // OK
所以我猜一个特征没有构造函数参数,所以没有 初始化它们的方式,因此不允许抽象私有字段。
如果它们是“受保护的”,那么子类可以使用预初始化来初始化它们 字段。这种方法允许子类看到这些字段。
如果我只想初始化它们然后隐藏它们怎么办? 如下例所示?
object holding {
trait trick {
protected val seed: Int // Can't be private
final def magic: Int = seed + 123
}
trait new_trick extends trick {
def new_magic: Int = magic + 456
def the_seed: Int = seed // [1]
}
def play: new_trick = new { val seed = 1 } with new_trick
def show_seed(t: new_trick): Int = t.the_seed // [2]
}
我不希望任何人都能看到种子,也就是说,不应允许 [2](因此 [1])。 有没有办法让特质做到这一点?
正如@Randall 和@pagoda_5b 所指出的,我的问题没有多大意义 感觉。但幸运的是 @Régis 和 @axel22 把它变成了另一个有趣的 问题并提供了解决问题的模式。
【问题讨论】:
-
拥有私有且未实现的东西怎么可能有意义?这是一个矛盾,因为它不是继承的,也永远无法实现,因此会阻止实例化带有此类成员的特征的任何子类型。
-
我不确定我是否关注你。如果您需要子类来定义种子(覆盖其定义),将其设为私有是没有意义的。也就是说,定义种子成员实现的子类将始终能够使用公共访问器显示它。我无法理解这种设计选择背后的需求。
-
我认为归结为能够让直接子特征定义
seed的值,同时使进一步的子特征(和外部代码)无法访问该值。有点像受保护的值(像对待子特征的受保护值一样对待,对于所有的事情都被视为私有的)。至于意义,我认为这个想法只是为了完全模拟可以通过参数(在类中)完成的操作,如他的示例所示。 -
抱歉,我的意思是“有点像 one-level 保护值”