Scala 访问修饰符有:private,protected,public;如果没有指定访问修饰符,默认情况下,Scala 对象的访问级别都是public。
1、私有(Private)成员用private关键字修饰,带有此标记的成员仅在包含了成员定义的class、object或者package内部可见,同样的规则还适用内部类。
- 类的例子
package p1{ class A{ private val class_member = "Alex" //类内部访问 class Inner{ println(class_member) // 正确 } } //类外部访问 class Outer{ println((new A).class_member) //错误 } }
- 包的例子
package p1{ package p2{ private class package_member //p2包内部 class inner{ new package_member //正确 } } //p2包外部 class outer{ new p2.package_member //错误 } }
2、保护(Protected)成员
在 scala 中,对保护(Protected)成员的访问比 java 更严格一些。因为它只允许保护成员在定义了该成员的class、object或者package的内部和class的子类中被访问。
- 类的例子
// protected package p1{ class Super{ protected val class_member = "Alex" //内部访问 class Inner{ println(class_member ) // 正确 } } //外部访问---子类 class Sub extends Super{ println(class_member ) // 正确 } //外部访问---非子类 class Other{ println((new Super).class_member ) //错误 } }
- 包的例子
package p1{ package p2{ protected class package_member //p2包内部 class inner{ new package_member //正确 } } //p2包外部 class outer{ new p2.package_member //错误 } }
3、公共(Public)成员
Scala 中,如果没有指定任何的修饰符,则默认为 public。这样的成员在任何地方都可以被访问。
- 类的例子
//public package p1 { class A { val class_member = "Alex" //内部访问 class Inner { println(class_member ) // 正确 } } //外部访问 class Other{ println((new A).class_member ) //正确 } }
- 包的例子
package p1{ package p2{ class package_member //p2包内部 class inner{ new package_member //正确 } } //p2包外部 class outer{ new p2.package_member //正确 } } //p1包外部 package p3{ class outer_p1{ new p1.p2.package_member //正确 } }
二、作用域保护private[x],protected[x]
这里的x指代某个class、object或package,它的意思是:在不加限定词的基础上,把访问权限扩大到X的内部。
package A { package B { private[A] class JustA } class MakeA { val a = new B.JustA // OK } } package C { class Error { val a = new A.B.JustA // error } }
三、作用域保护private[this],protected[this]
private[this]比private更严格,除了只能由内部代码访问,且修饰的成员不能被子类访问(如subMyInt2子类中mi2也是错误的,不能被访问)之外,还必须是调用该方法的对象才能访问。如上图中MyInt2中的m.mi2这句是错误的,因为它是由该函数的入参,也即传入的外部对象访问的,虽然它仍是MyInt2类型的对象,但是就是不能访问。
protected[this]和private[this]的相比,在能被内部代码访问的基础上,mi2变量也可以被子类访问,如subMyInt3子类中mi2这句是对的;但是仍然不能被外部对象访问,如MyInt3中m.mi2仍然是错的。
