我有一个特点:
trait A {
def some: Int
}
将物体混合在一起:
object B extends A {
def some = 1
}
问题是,是否有办法在some
中声明A
所有继承对象必须将some
方法声明为受保护的方式?是什么会让编译器对some
中B
的上述实现大喊大叫?
更新
只是澄清我的问题的目的:在一个组织内,有一些商定的软件开发标准。这些标准,例如'some
方法在继承private
'时始终被声明为trait A
,通常通过列出所有标准的规范或文档或通过工具等进行通信正如Jenkins等...我想知道我们是否可以更进一步,并在代码中使用这些标准,这样可以节省大量时间来纠正Jenkins提出的问题。
更新2: 我能想到的解决方案如下:
abstract class A(
protected val some: Int
){
protected def none: String
}
使用abstract class
代替trait
,并且默认情况下在构造函数中传递我需要protected
的函数或值:
object B extends A(some = 1) {
def none: String = "none"
}
请注意,在这种情况下,some
默认为protected
,除非开发人员决定通过其他方法公开它。但是,默认情况下,none
也不能保证protected
。
这适用于我上面描述的用例。这个实现的问题是,如果我们有abstract class
es的层次结构,我们必须将父级的所有构造函数参数添加到层次结构中的每个继承子级。例如:
abstract class A(
protected val some: Int
)
abstract class B(
someImp: Int,
protected val none: String
) extends A(some = someImp)
object C extends B(
someImp = 1,
none = "none"
)
相比之下,使用trait
,我们本来可以简单地写:
trait A{
protected val some: Int
}
trait B extends A{
protected val none: String
}
object C extends B{
val some = 1
val none = "none"
}
答案 0 :(得分:1)
我没有看到任何直接的方法来限制子类为继承成员选择更广泛的可见性。
这取决于你想隐藏字段的原因,但如果目的只是禁止最终用户访问字段,你可以使用稍微修改过的蛋糕模式:
trait A {
trait A0 {
protected def some: Int
}
def instance: A0
}
object B extends A {
def instance = new A0 {
def some = 5
}
}
是的,它看起来很讨厌,但是当有人试图做时,编译器会大喊:
B.instance.some
此解决方案的另一个版本只是在您的示例中执行操作(在A中将保护添加到成员“some”),但不要直接公开类型B的引用(总是返回类型A的引用)< / p>