Scala特征中的抽象私有字段
我碰巧发现它不允许有抽象的私有字段
特征,即 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指出的那样,我的问题并不多 解决方法
在允许子特征初始化的同时保持val私有的一种简单方法是将其定义为私有,但使用另一个受保护方法返回的值对其进行初始化.
然后子特征可以定义这个受保护的方法,以便更改初始值,但不能访问该值本身. 所以你会改变这个: trait A { protected val foo: Bar } 成: trait A { private val foo: Bar = initFoo protected def initFoo: Bar } 现在,只有特征A可以访问val foo.子特征可以通过definint initFoo设置foo的初始值,但不能访问foo本身: trait B extends A { protected def initFoo: Bar = ??? } 显然,initFoo本身仍然可以通过子特征访问. 但是如果它是一个问题(并且它确实在你的情况下因为种子是int类型因此你想要隐藏的是一个值而不仅仅是一个参考), trait A { // A "permit" to call fooInit. Only this instance can instantiate InitA abstract class InitA private[this]() // Unique "permit" private implicit def initA: InitA = null private def foo: Int = fooInit protected def fooInit( implicit init: InitA ): Int } trait B extends A { protected def fooInit( implicit init: InitA ): Int = 123 } 现在,如果B试图调用initFoo,编译器会抱怨它找不到类型为InitA的隐式(唯一的这样的实例是A.initA并且只能在A中访问). 正如我所说,它有点糟糕,axel22给出的包私有解决方案当然是一个更容易的替代方案(虽然它不会阻止任何人在同一个包中定义他们的子特征,因此会破坏访问限制). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |