Back OCAJP
There are 4 modifiers:
- private, only accessible within the class
- default, same as private plus accessible within the package
- protected, same as default plus accessible by subclasses
- public, accessible anywhere
Firstly, let's create the package structure in order to demo the access modifiers
OCAJP>mkdir home
OCAJP>mkdir stage
OCAJP>cd home
OCAJP>vi Mother.java
OCAJP>vi Daughter.java
OCAJP>vi Father.java
OCAJP>vi Home.java
OCAJP>cd ../stage
OCAJP>vi Singer.java
OCAJP>vi SuperStar.java
OCAJP>vi Stage.java
OCAJP>cd ..
OCAJP>javac home/*.java stage/*.java
The java contents are:
OCAJP>cat home/*.java stage/*.java
package home;
public class Daughter extends Mother{
int age = 15;
public static final String name = "Rachael";
String nickName = "Jay";
public void sing(String song) {System.out.println(name + " sing " + song);}
void sing(boolean happy) {if(happy) System.out.println(name + " sing");} //not ok at stage
}
package home;
public class Father {
int age = 40;
public static final String name = "Peter";
private void smoke() {System.out.println(name + " smoke in a corner");}
public static void main(String[] args) {
Father f = new Father();
f.smoke();
//private int a = 0; //error: illegal start of expression
Daughter d = new Daughter();
d.sing();
}
}
package home;
import stage.*;
class Home{
public static void main(String... args) {
Mother m = new Mother();
Father f = new Father();
Daughter d = new Daughter();
m.sing();
d.sing();
d.sing(true);
System.out.println(d.nickName + " at home");
//f.smoke(); //error: smoke() has private access in Father
d.sing("fun");
SuperStar s = new SuperStar();
s.sing(); //sing(); is protected, therefore SuperStar can inherited it, classes in home package can access it.
}
}
package home;
public class Mother {
int age = 40;
public static final String name = "Jean";
protected void sing() {System.out.println(name + " Sing dingdingdong");}
public static void main(String...args) {
Daughter d = new Daughter();
//System.out.println(name); //error: non-static variable name cannot be referenced from a static context
Mother m = new Mother();
System.out.println(m.name + " teaches " + d.nickName + " how to sing a song");
Father.main(new String[]{});
}
}
package stage;
interface Singer{
void sing(String song); //professional. interface and its methods by default have public access modifier
}
package stage;
import home.*;
class Stage{
public static void main(String args[]) {
Mother m = new Mother();
Father f = new Father();
Daughter d = new Daughter();
SuperStar s = new SuperStar();
System.out.println("mother: "+m.name+ ", father: " + f.name + ", daughter: "+d.name + ", super star: " + s.name);
//System.out.println(d.age); //error: age is not public in Daughter; cannot be accessed from outside package
//System.out.println(d.nickName + " on stage"); //error: nickName is not public in Daughter; cannot be accessed from outside package
//m.sing(); //error: sing() has protected access in Mother
//f.smoke(); //error: smoke() has private access in Father
//d.sing(); //error: no suitable method found for sing(no arguments)
//d.sing(true); //error: sing(boolean) is not public in Daughter; cannot be accessed from outside package
d.sing("fun");
/*sing() is protected, so SuperStar inherited it, however outside of home package, no other class can access it directly except child classes of Mother.java.
*/
/*sing() is protected, so SuperStar inherited it, however outside of home package, no other class can access it directly except child classes of Mother.java.
*/
//s.sing(); //error: method sing in class Daughter cannot be applied to given types;
//s.sing(false); //error: incompatible types: boolean cannot be converted to String
s.sing("out of woods");
s.show("out of woods");
s.sing("dingdingdong"); //not the same dingdingdong from sing()
}
}
package stage;
import home.*;
public class SuperStar extends Daughter implements Singer{
public void show(String song) {
System.out.print("perform under spotlight, ");
sing(song);
//sing(false); //error: incompatible types: boolean cannot be converted to String
Mother m = new Mother();
System.out.println("This song is for my mother "+m.name);
sing(); //sing() is protected, so SuperStar can inherit it, though it is out of home package, SuperStar can still access it in its own class.
}
public static void main(String...args) {
Father f = new Father();
System.out.println("at stage, override the main in Mother.java, you are on camera " + f.name);
}
}
On the above classes, access modifiers are applied to both instance variables and methods. The public and private are straight-forward. The default access modifier is also easy to understand -- only accessible in the same package.
The tricky part is the protected access modifier. protected variable or methods are accessible outside the package, however, they must be accessed inside the subclass. Mother only sing() dingdingdong at home, she don't want to sing() at stage. Super star daughter performs show() on stage, she sing(songs) in public, she sing() dingdingdong in a public show() method as super star on stage because she wants to sing(); however, neither stage nor audience (you write a stage/Audience.java and try out) can ask her to sing() protected dingdingdong on stage as super star, only home and family members can ask her to sing() protected dingdingdong at home as daughter.
Let's see how the program runs.
OCAJP>java home/Home
Jean Sing dingdingdong
Jean Sing dingdingdong
Rachael sing
Jay at home
Rachael sing fun
Jean Sing dingdingdong
OCAJP>java stage/Stage
mother: Jean, father: Peter, daughter: Rachael, super star: Rachael
Rachael sing fun
Rachael sing out of woods
perform under spotlight, Rachael sing out of woods
This song is for my mother Jean
Jean Sing dingdingdong
Rachael sing dingdingdong
Rachael sing dingdingdong
OCAJP>
OCAJP>java home/Father
Peter smoke in a corner
Jean Sing dingdingdong
OCAJP>java home/Mother
Jean teaches Jay how to sing a song
Peter smoke in a corner
Jean Sing dingdingdong
OCAJP>java home/Daughter
Jean teaches Jay how to sing a song
Peter smoke in a corner
Jean Sing dingdingdong
OCAJP>
OCAJP>java stage/SuperStar
at stage, override the main in Mother.java, you are on camera Peter
Back OCAJP