TurkuBasicOOPinJava / Week 5: Class hierarchies /05A. Encapsulation and inheriting [++Attribute's 4 visibility levels]
KaiquanMah's picture
public, protected, no set level, private
5b9cf26 verified
The child class inherits all the traits of the parent class.
However, the child class does NOT have DIRECT ACCESS to the 'features of the parent class that are protected by the private wrapper'.
If an attempt is made to reference the Name attribute of the Person attribute of the Student class, a translation error occurs:
class Student extends Person {
private int studypoints;
public Student(String name, String email, int studypoints) {
this.name = name; // HERE
this.studypoints = studypoints;
}
}
However, it would often be convenient to refer to attributes in a child class.
But if the private wrapper is removed, the client also has direct access to modify the attributes.
So how to solve the dilemma?
============
Visibility level protected
In Java, the problem is solved by a 'third visibility matrix'.
In addition to private and public, the visibility wrapper can be set to protected.
A feature protected by the protected wrapper is
- is AVAILABLE in the CHILD class but
- is NOT VISIBLE to CLIENTS of the class
The table below summarizes all 4 visibility definitions in Java
(including the omission of a visibility wrapper as a visibility definition in Java):
Visibility levels in Java
Level Visible within class Visible within package Visible within CHILD classes Visible everywhere
public yes yes yes yes
protected yes yes yes no <= HERE
no set level yes yes no no
private yes no no no
Let's now change the definition of the Person class so that the visibility of attributes is 'protected' instead of 'private':
class Person {
// 'protected' attribute - subclasses can directly access, clients cant directly access
protected String name;
protected String email;
public Person(String name, String email) {
this.name = name;
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email= email;
}
}
Now the Student class can use inherited attributes.
The method printStudent refers directly to the attributes defined in the parent class Person.
class Student extends Person {
private int studypoints;
public Student(String name, String email, int studypoints) {
//HERE
super(name, email);
this.studypoints = studypoints;
}
public void printStudent() {
// Now in the child class we can refer straight to
// the attributes defined in the parent class
System.out.println("Name" + name);
System.out.println("Email:" + email);
System.out.println("Studypoints: " + studypoints);
}
public int getStudypoints() {
return studypoints;
}
public void setStudypoints(int studypoints) {
this.studypoints = studypoints;
}
}