object P{
object P1{
class A{
//I want only classes/objects that extends A AND in the package P1 can access x
//It means, the modifier `protected` and the qualifier [P1] is combined with operator `AND`:
//protected AND [P1] means, x is:
// protected: not in subclass then not accessible
// AND [P1]: not in [P1] then not accessible
//protected OR [P1] means, x is:
// protected: not in subclass then not accessible
// OR [P1]: not in [P1] then not accessible
protected[P1] val x = 1
//Like `protected[this]`: y is protected AND [this]
//because y is accessible only in subclass AND in the same object
//(access to y in B2.f2 is permit but in B2.f3 is deny)
//(if protected[this] == protected OR [this] then protected[this] == protected :D)
protected[this] val y = 2
//Also, I don't know why the following code is valid
//(scalac 2.10.0 compile it!). Is this an error in scala compiler?
//But this strange modifiers combination is also not what I want!
private[P1] protected val z = 1
}
class B{
def f(a: A) = a.x + a.z //permit!
}
}
object P2{
class B2 extends P1.A{
def f = x + z //also permit!
def f2 = y //permit. OK
def f3(b: B2) = b.y //deny. OK
}
}
}
我知道x
上的protected [P1]修饰符与java的受保护修饰符相同。但是,如何仅允许从包P1中扩展A AND的类/对象访问A.x
编辑: @Randal问:“你为什么关心包装约束?这对你有什么帮助?”
我有一个复杂类的大型项目。我将课程分成几个特点。但是某些特征中的某些成员只打算在一些(但不是全部)其他子特征中使用。因此,我在一个包中组织了所有需要可访问性的特征。而那些需要这些特征逻辑的即时类被放入另一个包中。但是这个班只需要访问一些特质的成员。然后我想只有所需的成员才能在课堂上看到:
package p.base
private[base] trait A{
//x is intent to be used only in trait B and C
protected[base] val x = 1
}
private[base] trait B{this: A =>
//f is intent to be used only in trait C
protected[base] def f = x
//f2 will be used in global.D
def f2 = f
}
private[p] trait C extends B with A{...}
package p.global
class D extends p.base.C{
def g = f2
}
答案 0 :(得分:0)
仅使用专门的访问修饰符是不可能的。要获得编译时限制,您可以使用这样的技术
object P {
object P1 {
class A {
@implicitNotFound(msg = "Only accessible when extending from A")
sealed trait OnlyA
protected[this] implicit object OnlyA extends OnlyA
private[P1] def x(implicit ev: A#OnlyA) = 1
private[P1] val z = 1
}
class B {
def f(a: A) = a.z + a.x // Will not work
}
class C extends A {
def f(a: A) = a.z + a.x // Works
}
}
object P2 {
class B2 extends P1.A {
def f = x // Will not work
def f(a: P1.A) = a.x + a.z // Will not work
}
}
}
答案 1 :(得分:0)
您可以使用private[PkgName]
保护构造函数并提供工厂以提供公共创建,因此子类化仅限于该包:
package pkg
...
class A private[pkg] { ...
}
object A {
def apply(): A = new A
}
...