修饰符:
- Scala 访问修饰符基本和Java的一样,分别有:private,protected,public。
- 如果没有指定访问修饰符,默认情况下,Scala 对象的访问级别都是 public。
- Scala 中的 private 限定符,比 Java 更严格,在嵌套类情况下,外层类甚至不能访问被嵌套类的私有成员。
私有(Private)成员
用 private 关键字修饰,带有此标记的成员仅在包含了成员定义的类或对象内部可见,同样的规则还适用内部类。
class Outer{
class Inner{
private def f(){println("f")}
class InnerMost{
f() // 正确
}
}
(new Inner).f() //错误
}
(new Inner).f( ) 访问不合法是因为 f 在 Inner 中被声明为 private,而访问不在类 Inner 之内。
但在 InnerMost 里访问 f 就没有问题的,因为这个访问包含在 Inner 类之内。
Java中允许这两种访问,因为它允许外部类访问内部类的私有成员。
保护(Protected)成员
在 scala 中,对保护(Protected)成员的访问比 java 更严格一些。因为它只允许保护成员在定义了该成员的的类的子类中被访问。而在java中,用protected关键字修饰的成员,除了定义了该成员的类的子类可以访问,同一个包里的其他类也可以进行访问。
package p{
class Super{
protected def f() {println("f")}
}
class Sub extends Super{
f()
}
class Other{
(new Super).f() //错误
}
}
上例中,Sub 类对 f 的访问没有问题,因为 f 在 Super 中被声明为 protected,而 Sub 是 Super 的子类。相反,Other 对 f 的访问不被允许,因为 other 没有继承自 Super。而后者在 java 里同样被认可,因为 Other 与 Sub 在同一包里。
公共(Public)成员
Scala中,如果没有指定任何的修饰符,则默认为 public。这样的成员在任何地方都可以被访问。
class Outer {
class Inner {
def f() { println("f") }
class InnerMost {
f() // 正确
}
}
(new Inner).f() // 正确因为 f() 是 public
}
作用域保护
Scala中,访问修饰符可以通过使用限定词强调。格式为:
private[x]
或
protected[x]
这里的x指代某个所属的包、类或单例对象。如果写成private[x],读作"这个成员除了对[…]中的类或[…]中的包中的类及它们的伴生对像可见外,对其它所有类都是private。
这种技巧在横跨了若干包的大型项目中非常有用,它允许你定义一些在你项目的若干子包中可见但对于项目外部的客户却始终不可见的东西。
private和private[this]:
(1)对于类私有的字段,Scala生成私有的getter/setter方法,就是前者;
(2)对于对象私有的字段,Scala不生成getter/setter方法,就是后者。
实操
创建一个Stu的类,并对其中的属性,方法设置作用域及访问修饰符
object DemoPrivate {
class Stu{
val name = "陛下"
private val age = 18 //本类 伴生对象才能访问
//this代表当前对象
private[this] val sal = 30000 //一旦加上this之后,只能在本类使用
protected val height:Int = 180 //本类、子类、伴生对象才能使用
protected[this] val weight = 140 //一旦加上this,只能在本类调用
def getInfo:Unit = {
println("公共的信息")
}
protected def getProtected:Unit = {
println("protected的信息")
}
private def getprivate:Unit = {
println("private的信息")
}
protected[DemoPrivate] val exclusive1 = "exclusive1"
private[DemoPrivate] val exclusive2 = "exclusive2"
}
创建一个Stu的子类
class Xiaoming extends Stu{
//private修饰的方法不能调用
getInfo
getProtected
var stu = new Stu
stu.name
stu.height
}
发现Stu的子类只能访问public和protected修饰符修饰的属性及方法,而且,当 protected[x]中x为this时,其子类也不能访问
随意创建一个类
class Xx{
var stu = new Stu
//将其中范围选择至整个对象,那么凡是在这个对象之中,都可以访问
stu.exclusive1
stu.exclusive2
stu.name
}
发现被private和protected修饰的统统不能访问,但是修饰符指定范围为最外层的类时,就可访问了,如exclusive1,exclusive2
创建其伴生类
object Stu{
def main(args: Array[String]): Unit = {
val stu = new Stu
stu.age
stu.height
stu.name
}
发现只要不是 protected[this], private[this],都可访问