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
}
}
}
I know that protected[P1] modifier on x
is same as java's protected. But, how to allow access to A.x only from classes/objects that extends A AND in the package P1?
EDIT: @Randal ask: "Why do you care about the package constraint? What does that get you?"
I have a large project with a complex class. I split the class to several trait. But some members in some traits is intend to be used only in some (but not all) other sub-traits. So, I organize all traits that need the accessibility in one package. And the instantable class that need logic of those traits is put in another package. But the class need access to only some traits' members. Then I want only the needed members is visible to the class:
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
}