Scala访问修饰符–私有,受保护的和公共的
通过访问修饰符可以实现将范围限制在某些地方。
公共,私有和受保护是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类,而不会出现任何错误。
下表描述了类,包,子类和所有类的各种访问修饰符的可访问性。
Modifier | Class | Package | Subclass | Every class |
public | Yes | Yes | Yes | Yes |
protected | Yes | No | Yes | No |
private | Yes | No | No | No |
保护范围
访问修饰符可以在[]中带有修饰符后缀。
类型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)