Skip to content

Scala 访问修饰符

Scala 使用访问修饰符 private、protected 和默认(public)来控制 class、trait 和 object 成员的可见性。Scala 还支持带限定符的修饰符,如 private[package] 或 protected[this],以实现更细粒度的控制。

如果未指定访问修饰符,则成员是 public 的。Public 成员可以在包含该成员的 class/object/package 可访问的任何地方访问。

class PublicExample {
val publicField = 10
def publicMethod(): String = "Accessible everywhere"
}
val ex = new PublicExample()
ex.publicField // OK
ex.publicMethod() // OK

标记为 private 的成员仅在其包含该成员定义的 class 或 object 的词法作用域内可见,包括嵌套的 class 或 object。

class Outer {
class Inner {
private def secret() = println("Inner secret")
def revealSecret() = secret() // OK: Access within Inner
class InnerMost {
// secret() // Error: Not accessible from InnerMost (though nested, different class scope)
// Correction: Scala allows access from *enclosing* class scope
def accessOuterInnerSecret() = secret() // OK: InnerMost is inside Inner
}
}
private val outerSecret = "Outer secret"
// (new Inner).secret() // Error: secret is private to Inner, cannot access from Outer
val innerInstance = new Inner()
innerInstance.revealSecret() // OK: Calling public method of Inner
}

注意:与 Java 不同,外部 class 不能直接访问其内部 class 的 private 成员(除非使用带限定符的修饰符)。

标记为 protected 的成员只能在其定义所在的 class 的子类中访问。与 Java 不同,Scala 中的 protected 默认不授予包访问权。

package scopeA {
class Superclass {
protected def protectedMethod() = println("Superclass protected method")
}
class Subclass extends Superclass {
def accessProtected() = protectedMethod() // OK: Subclass accessing protected member
}
class Other {
val sup = new Superclass()
// sup.protectedMethod() // Error: protectedMethod not accessible from Other (not a subclass)
}
}
package scopeB {
// import scopeA._ // Needed if in different files
class AnotherSubclass extends scopeA.Superclass {
def accessProtectedToo() = protectedMethod() // OK: Subclass in different package
}
}

带限定符的访问修饰符 (Access Qualifiers):

Section titled “带限定符的访问修饰符 (Access Qualifiers):”

Scala 允许使用方括号 [] 中的限定符来细化 private 和 protected 的作用域。private[X] 或 protected[X] 意味着该成员在限定的 package X、class X 或单例 object X 的范围内都可以访问。

对象私有(Object-private)。成员只能从同一对象实例内部访问。即使是同一 class 的其他实例也无法访问它。这是限制最严格的修饰符。

class Counter {
private[this] var count = 0 // Only accessible via 'this'
def increment() = { count += 1 }
def current = count
def isLess(other: Counter): Boolean = {
// count < other.count // Error: Cannot access private[this] 'count' of 'other' instance
this.count < other.current // OK: Accessing via public method 'current'
}
}

使成员对指定作用域内的任何代码都可访问。

package vehicle {
class Engine {
// Visible to any code within the 'vehicle' package
private[vehicle] def start() = println("Engine starting...")
}
class Car {
val engine = new Engine()
def turnOn() = {
engine.start() // OK: Car is in package 'vehicle'
}
}
package parts {
class SparkPlug {
// Cannot access engine.start() here, as parts is nested deeper than 'vehicle'
}
}
}
package navigation {
// Cannot access engine.start() here, different package
}

类似于 private[X],但访问仅限于作用域 X 内的子类。

这些修饰符提供了对封装的细粒度控制,允许精确定义可见性边界。