文章永久连接:https://tech.souyunku.com/2983
访问修饰符是实现面向对象三大特性重要的支持语法,有了访问修饰符,我们就可以界定一个包,一个类,一个对象属性,一个对象方法的可见粒度。
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)成员
用 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)成员
用 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。
这种技巧在横跨了若干包的大型项目中非常有用,它允许你定义一些在你项目的若干子包中可见但对于项目外部的客户却始终不可见的东西。
package bobsrocckets{
package navigation{
private[bobsrockets] class Navigator{
protected[navigation] def useStarChart(){}
class LegOfJourney{
private[Navigator] val distance = 100
}
private[this] var speed = 200
}
}
package launch{
import navigation._
object Vehicle{
private[launch] val guide = new Navigator
}
}
}
上述例子中,类Navigator被标记为private[bobsrockets]就是说这个类对包含在bobsrockets包里的所有的类和对象可见。
比如说,从Vehicle对象里对Navigator的访问是被允许的,因为对象Vehicle包含在包launch中,而launch包在bobsrockets中,相反,所有在包bobsrockets之外的代码都不能访问类Navigator。
干货推荐
附录:Scala 教程:系列文章
- 一、Scala 教程: 教程
- 二、Scala 教程: 简介
- 三、Scala 教程: 安装
- 四、Scala 教程: 基础语法
- 五、Scala 教程: 数据类型
- 六、Scala 教程: 中文乱码解决
- 七、Scala 教程: 变量
- 【当前读到】八、Scala 教程: 访问修饰符
- 九、Scala 教程: 运算符
- 十、Scala 教程: if…else 语句
- 十一、Scala 教程: 循环
- 十二、Scala 教程: 函数
- 十三、Scala 教程: 闭包
- 十四、Scala 教程: 字符串
- 十五、Scala 教程: 数组
- 十六、Scala 教程: Collection
- 十七、Scala 教程: Iterator(迭代器)
- 十八、Scala 教程: 类和对象
- 十九、Scala 教程: Trait(特征)
- 二十、Scala 教程: 模式匹配
- 二十一、Scala 教程: 正则表达式
- 二十二、Scala 教程: 异常处理
- 二十三、Scala 教程: 提取器(Extractor)
- 二十四、Scala 教程: 文件 IO
- 二十五、Scala 教程: do…while 循环
- 二十六、Scala 教程: 函数 – 默认参数值
- 二十七、Scala 教程: 高阶函数
- 二十八、Scala 教程: 函数嵌套
- 二十九、Scala 教程: Map(映射)
- 三十、Scala 教程: 指定函数参数名
- 三十一、Scala 教程: 偏应用函数
- 三十二、Scala 教程: 匿名函数
- 三十三、Scala 教程: 元组
- 三十四、Scala 教程: 函数传名调用(call-by-name)
- 三十五、Scala 教程: 递归函数
- 三十六、Scala 教程: Set(集合)
- 三十七、Scala 教程: 函数柯里化(Currying)
- 三十八、Scala 教程: 函数 – 可变参数
- 三十九、Scala 教程: Option(选项)
- 四十、Scala 教程: do…while 循环
- 四十一、Scala 教程: while 循环
- 四十二、Scala 教程: List(列表)
- 四十三、Scala 教程: break 语句