开发者学堂课程【Scala 核心编程-基础:Scala 包的可见性讲解】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/609/detail/8961
Scala 包的可见性讲解
内容介绍:
一、Scala 包的可见性介绍
二、Scala 包的可见性和访问修饰符的使用
三、总结
一、Scala 包的可见性介绍
1、Scala 包的可见性与 java 的区别
在 java 中,访问权限有四种:public,private,protected 和默认,在 scala 中,也可以通过修饰符达到效果,但是使用上有区别。
2、范例:
object Testvisit{
def main(args: Array[String]): Unit = {
val c = new Clerk()
c.showlnfo()
Clerk test(c)
}
}
//类
class Clerk{
//该属性没有加任何修饰符
var name:String = "jack"
private var sal:Double = 9999.9
//定义了一个方法
def showinfo():Unit={
//在本类可以使用私有的。var name:String = "jack"和private var sal:Double = 9999.9 在底层都是私有的,区别是 var name:String = "jack" 会生成一个可读可写的方法,private var sal:Double = 9999.9只能生成一个只读的方法。
println("name" + name +"sal="+sal)
//当一个文件中同时出现了 class Clerk 和 object Clerk:class Clerk 称为伴生类,object Clerk 称为伴生对象。
//由于 scala 设计者认为 static 不是一个面向对象的范畴,所以将 static 关键字删除了。但是 Scala 是基于 jvm 运行的,要与 java 接轨,而 Java 中有 static,scala 中没有 static ,就会出现问题。所以设计者又设计了伴生类和伴生对象的概念解决这个问题。
//伴生类中写非静态内容和非静态属性,伴生对象是静态内容。
//在伴生对象中可以访问 Clerk 的私有属性,但是不能在其他地方使用,比如在 def main(args: Array[String]): Unit = 下访问 c.sal 就会报错。
//私有属性能够在本类访问,也能在它的伴生对象中访问。
object Clerk{
def test(c:Clerk):Unit={
//这里体现出在伴生对象中,可以访问 c.sal
println(“test() name="+c.name+"sal="+c.sal)
}
}
二、Scala 包的可见性和访问修饰符的使用
1、当属性访问权限为默认时,从底层看属性是 private 的,但是因为提供了 xxx_$eq()[类似setter]/xxx()[类似getter]方法,因此从使用效果看任何地方都可以访问。
2、当方法访问权限为默认时,默认为 public 访问权限。当属性是默认时底层是私有的,当方法是默认时,属性是公开的。案例演示:
class Clerk{
var name:String = "jack"
private var sal:Double = 9999.9
//定义了一个方法,这是一个公开的方法。
def showinfo():Unit={
3、private 为私有权限,只在类的内部和伴生对象中使用,无论是私有属性还是私有方法都只能在类的内部和伴生对象中使用。
4、protected 为受保护权限,scala 中受保护权限比 Java 中更严格,只能在子类访问,同包无法访问。案例演示:
class Clerk{
var name:String = "jack"
private var sal:Double = 9999.9
//属性 age 使用了 protected 修饰, protected 就无法在同包中使用。
protected
v
ar age=10
def showinfo():Unit={
//调用 c.age 报错。在 java 中 protected 可以在同一个包中使用,但是在 scala 中不能使用。
object Testvisit{
def main(args: Array[String]): Unit = {
val c = new Clerk()
println
(c.age)
5、在 scala 中没有 public 关键字,不能用 public 显式的修饰属性和方法。比如 public var job:String=”大数据工程师”这样的写法就是错误的,在 scala 中不能使用 public ,但是使用效果是一样的。
6、包访问权限(表示属性有了限制。同时包也有了限制),这是 scala新增的内容,体现了 scala 包使用的灵活性,相当于扩大了访问权限的范围。
案例演示一:
package com.atguigu. scala
class Person {
private[scala] val pname="hello”
//增加包访问权限后,private 同时起作用,不仅同类可以使用,同时 com.atguigu.scala 中包下其他类也可以使用。
}
//也可以将可见度延展到上层包。
private[atguigu] val descripti on=" zhangsan”
说明:private 也可以变化,比如 protected[atguigu],非常灵活。
案例演示二:
class Person {
val name="
jack
”
//创建一个 person 对象。
val p1=
new
person
//可以使用 name,因为 val name="jack” 底层会生成两个共用方法。
println
(p1.name)
如果用 private 修饰:private val name="jack” 就不能调用 name。
//增加一个包访问权限就可以继续调用 name。
class Person {
private [visit] val name="jack”
//private [visit] 表示仍然是私有的,但是扩大了包的访问范围,在 visit 包以及其子包下都可以使用 name 属性。
//把[visit]换为[chapter07],意味着这个包以及它下面的子包都能进行访问。
private [chapter07] val name="jack”
// Private 改为 protected 是一样的效果,如果不加权限[visit]就不能进行访问。
protected [visit] val name="jack”
三、总结
1、scala 中包的可见性介绍:在 Java 中,访问权限分为: public,private,protected 和默认。在 Scala 中,可以通过类似的修饰符达到同样的效果。但是使用上有区别。代码案例:
object Testvisit{
def main(args: Array[String]): Unit = {
val c = new Clerk()
c.showlnfo()
Clerk test(c)
}}
class Clerk{
var name:String = "jack"
private var sal:Double = 9999.9
def showinfo():Unit={
println("name" + name +"sal="+sal)
object Clerk{
def test(c:Clerk):Unit={
//这里体现出在伴生对象中,可以访问 c.sal
println(“test() name="+c.name+"sal="+c.sal)
}}
2、Scala 包的可见性和访问修饰符的使用。
(1)、当属性访问权限为默认时,从底层看属性是 private 的,但是因为提供了xxx_$eq()[类似setter]/xxx()[类似getter]方法,因此从使用效果看任何地方都可以访问。
(2)、当方法访问权限为默认时,默认为 public 访问权限。
(3)、private 为私有权限,只在类的内部和伴生对象中使用。
(4)、protected 为受保护权限,scala 中受保护权限比 Java 中更严格,只能在子类访问,同包无法访问。
(5)、在 scala 中没有 public 关键字,不能用 public 显式的修饰属性和方法。
(6)、包访问权限(表示属性有了限制。同时包也有了限制),这是 scala新增的内容,体现了 Scala 包使用的灵活性。
案例演示:
package com.atguigu. scala
class Person {
private[scala] val pname="hello”
//增加包访问权限后,private 同时起作用,不仅同类可以使用,同时com.atguigu.scala 中包下其他类也可以使用。
}
//也可以将可见度延展到上层包。
private[atguigu] val descripti on=" zhangsan”
说明:private 也可以变化,比如 protected[atguigu],非常灵活。
(7)、整体代码演示:
P
ackage
com
.guigu.chapter07.visit
object Testvisit{
def main(args: Array[String]): Unit = {
val c = new Clerk()
c.showlnfo()
Clerk test(c)
//创建一个 person 对象。
val p1=new person
println(p1.name)
}
}
//类
class Clerk{
var name:String = "jack"
private var sal:Double = 9999.9
protected var age=10
var job:String=”大数据工程师”
def showinfo():Unit={
//在本类可以使用私有的。
println("name" + name +"sal="+sal)
object Clerk{
def test(c:Clerk):Unit={
//这里体现出在伴生对象中,可以访问 c.sal
println(“test() name="+c.name+"sal="+c.sal)
}
}
class Person {
//增加一个包访问权限
//private[visit]:1,仍然是 private 2.在 visit包(包括子包)下也可以使用 name ,相当于扩大访问范围。
protected[visit] val name = "jack"
}