The restriction of scope to certain places is realized with the help of access modifiers. public, private and protected are the three access modifiers used in Scala. Include the keywords private/protected/public in the definition of class, object or package to enforce the corresponding scope. If none of these keywords are used, then the access modifier is public by default.
Private member
Private members are available only inside the class or to the object containing the member definition. The private access modifier can be used for variables and methods as well. Consider an example to show the private members;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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() } |
Here we define an outer class Student and an inner class Student1 with variable “sage” which is a private member.
In the StudentAge class we just access and add 4 to the sage(student age) variable. Now when we try accessing the variable sage from another object instantiated as “new Student1”, an access error is thrown as below.
In Student1 class we also have defined a private method studage() in which we are just printing the student age. We are then calling this method from within StudentAge class. This is allowed as the Student age class is the innermost nested class of Student1. studage method cannot be accesed from StudentAge class.
Run the above example code to see the error message as shown below;
1 2 3 4 5 6 |
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() |
Below image shows the complete code execution in Scala shell.
Protected Member
Protected members can be accessed from subclasses of the class in which the member is defined (inherited class). This can also be used for methods as well as variables.
Consider an example shown below;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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() } |
The class Student
is created consisting of a variable sid and a method studId() in which we are printing the student id.
Next, we are creating a class CollegeStudent
extending the super class Student and incrementing the variable sid by 6 and then invoke the method studId().
We create another class TestStudent and try to the access the sid variable and then call studid() after creating a new object of the Student class. Since TestStudent is not a subclass of Student, an error is thrown as sid and studId() are not accessible. This is because they are specified as protected members and can only be accessed by subclassing the main class. Class CollegeStudent is a subclass of Student and hence can access sid variable and studId method.
Run the above code to see the following error in output.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<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() ^ |
But when we try to run the program and access the variable and method from inside CollegeStudent
class, there won’t be any errors.
Public member
The default access modifier is public. When the keywords private or protected is not specified then the members are treated as public by the compiler and we don’t have to explicitly specify the keyword “public”.
Consider an example to depict the public members;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class Student { class Stud { var sname = "Adam" def studName() { println("Student name is :"+sname) } class TestStud { studName() } } (new Stud).sname (new Stud).studName() } |
Student class is created with an inner class Stud along with variables sname and method studName which prints the student name.
TestStud class is created calling the studName() method. Now when we try accessing the sname variable or invoke studName() outside the Stud class, it becomes accessible since attributes with access modifier public is visible to any of the classes.
When we execute the above code the Student class is created successfully without any errors.
The following table depicts the accessibility of various access modifiers for class, package, subclass and all classes.
Modifier | Class | Package | Subclass | Every class |
public | Yes | Yes | Yes | Yes |
protected | Yes | No | Yes | No |
private | Yes | No | No | No |
Scope of Protection
Access modifiers can be suffixed with qualifiers in the []. The modifiers of type protected[Y] or private[Y] specifies that access is provided upto Y where Y can be a package, class or singleton object.
Consider an example to depict the usage of these qualifiers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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) } } } } |
To type the above code in the shell we have to first enter the paste mode by typing :paste -raw
and then insert this code. Once the code is inserted completely press ctrl-D to exit from the paste mode and run the code (enter key). In the normal mode an error is thrown as illegal start of definition after declaring the package.
Here we are declaring packages student and graduatestudent. We are defining a class Stud with the variable “degree” having protected access modifier qualified by the package name graduatestudent, variable marks of private access qualified to student package and age variable for the current instance of the Stud class. studdegree() method is defined in which we are trying to access the variables degree, marks and age. The variable age cannot be accessed and so it throws an error as below.
1 2 3 4 5 |
value age is not a member of student.graduatestudent.Stud println(stu.age) <img class="alignnone wp-image-32167 size-full" src="https://all-learning.com/wp-content/uploads/2015/04/Scala-private-access-modifier3.png" alt="Scala-private-access-modifier" width="1200" height="628" /> |
Key points about the variables degree, marks and age
- The variable degree can be accessed by any class within the package graduatestudent
- The variable marks can be accesed by any class within the package student.
- The variable age can be accessed only on the implicit objects within instance methods(this).
That’s all for access modifiers in Scala, its very close to java access modifiers except the default modifier is public here. We will look more Scala core features in the coming posts.