Scala访问修饰符–私有,受保护的和公共的

时间:2020-02-23 14:41:44  来源:igfitidea点击:

通过访问修饰符可以实现将范围限制在某些地方。
公共,私有和受保护是Scala中使用的三个访问修饰符。
在类,对象或者包的定义中包括关键字private/protected/public,以强制执行相应的范围。
如果未使用这些关键字,则默认情况下,访问修饰符为public。

私人会员

私有成员仅在类内部或者包含成员定义的对象中可用。
private访问修饰符也可以用于变量和方法。
考虑一个显示私人成员的例子;

class Student {

class Student1 {

private var sage = 0
private def studage() {
println("Student Age is :"+sage)
}
}

class StudentAge {
sage = sage + 4
studage()
}

(new Student1).sage

(new Student1).studage()

}

其中我们定义一个外部类Student和一个内部类Student1,它们的变量" sage"是一个私有成员。

在StudentAge类中,我们仅访问sage(学生年龄)变量并将其添加4。
现在,当我们尝试从实例化为" new Student1"的另一个对象访问变量sage时,将引发如下访问错误。

在Student1类中,我们还定义了一个私有方法studage(),其中我们只是在打印学生年龄。
然后,我们从StudentAge类中调用此方法。
这是允许的,因为Student年龄类是Student1的最内层嵌套类。
不能从StudentAge类访问studage方法。

运行上面的示例代码以查看错误消息,如下所示;

error: variable sage in class Student1 cannot be accessed in Student.this.Student1

(new Student1).sage

error: method studage in class Student1 cannot be accessed in Student.this.Student1

(new Student1).studage()

下图显示了Scala shell中完整的代码执行。

受保护的成员

可以从定义成员的类的子类(继承的类)中访问受保护的成员。
这也可以用于方法和变量。

考虑下面的示例;

class Student {
protected var sid = 12
protected def studId() {
println("Student Id is :"+sid)
}
}

class CollegeStudent extends Student {
sid = sid + 6
studId()
}

class TestStudent {
(new Student).sid
(new Student).studId()
}

创建的"学生"类由变量sid和方法studId()组成,我们其中打印学生ID。

接下来,我们将创建一个类" CollegeStudent",该类扩展超类Student,并将变量sid递增6,然后调用方法studId()。

我们创建另一个类TestStudent并尝试访问sid变量,然后在创建Student类的新对象后调用studid()。
由于TestStudent不是Student的子类,因此将抛出错误,因为sid和studId()无法访问。
这是因为它们被指定为受保护成员,并且只能通过对主类进行子类化来访问。
CollegeStudent类是Student的子类,因此可以访问sid变量和studId方法。

运行上面的代码以查看以下错误输出。

<console>:9: error: variable sid in class Student cannot be accessed in Student
 Access to protected method sid not permitted because
 enclosing class TestStudent is not a subclass of
 class Student where target is defined
     (new Student).sid
                   ^
<console>:10: error: method studId in class Student cannot be accessed in Student
 Access to protected method studId not permitted because
 enclosing class TestStudent is not a subclass of
 class Student where target is defined
     (new Student).studId()
                   ^

但是,当我们尝试运行程序并从" CollegeStudent"类内部访问变量和方法时,不会有任何错误。

public成员

默认访问修饰符为public。
如果未指定关键字private或者protected,则编译器会将成员视为public,而我们不必显式指定关键字" public"。

考虑一个描述公众成员的例子;

class Student {

class Stud {
var sname = "Adam"
def studName() {
println("Student name is :"+sname)
}

class TestStud {
studName()
}
}

(new Stud).sname

(new Stud).studName()
}

使用内部类Stud以及变量sname和方法studName创建学生类,该变量显示学生名。

创建TestStud类,调用studName()方法。
现在,当我们尝试访问sname变量或者在Stud类之外调用studName()时,由于具有访问修饰符public的属性对于任何类都是可见的,因此它可以访问。

当我们执行上述代码时,将成功创建Student类,而不会出现任何错误。

下表描述了类,包,子类和所有类的各种访问修饰符的可访问性。

ModifierClassPackageSubclassEvery class
publicYesYesYesYes
protectedYesNoYesNo
privateYesNoNoNo

保护范围

访问修饰符可以在[]中带有修饰符后缀。
类型protected [Y]或者private [Y]的修饰符指定提供访问权限,直到Y,其中Y可以是包,类或者单例对象。

考虑一个描述这些限定词用法的示例

package student {

package graduatestudent {

class Stud {
protected[graduatestudent] var degree = null
private[student] var marks = 60
private[this] var age = 0

def studdegree(stu:Stud) {
println(stu.degree)
println(stu.marks)
println(stu.age)
}
}
}
}

要在shell中键入上面的代码,我们必须首先通过键入:paste -raw进入粘贴模式,然后插入此代码。
完全插入代码后,按ctrl-D退出粘贴模式并运行代码(输入键)。
在正常模式下,声明程序包后,将由于定义的非法开始而引发错误。

其中我们声明学生和研究生套餐。
我们正在定义一个Stud类,其变量"学位"具有受保护的访问修饰符,该修饰符由包名称毕业生学生限定,私人访问的变量标记符合学生包的要求,并且为Stud类的当前实例具有年龄变量。
定义了studdegree()方法,在该方法中我们尝试访问变量度,标记和年龄。
变量age无法访问,因此会引发如下错误。

value age is not a member of student.graduatestudent.Stud
println(stu.age)