접근 제어자에는 public과 private외에 두 가지가 더 있는데, protected와 default다.
1) protected : 상속관계에 있다면 서로 다른 패키지에 있는 클래스의 접근도 허용한다.
2) default : 접근 제어 지시자가 없는 경우를 의미하는데, 접근 제어자가 없는 메소드는 같은 패키지에 있고 상속 관계에 있는 메소드에 대해서만 접근을 허용한다.
아래 표는 생활코딩에서 정리한 표인데 기가 막히게 정리를 잘해놓으셨다.
아래 코드를 통해 좀 더 자세히 알아보자.
Class SameClassChecker {
public SameClassChecker(){
//같은 클래스
this._public();
this._protected();
this._default();
this._private();
}
public void _public(){
System.out.println("public");
}
protected void _protected(){
System.out.println("protected");
}
void _default(){
System.out.println("default");
}
private void _private(){
System.out.println("private");
}
위의 SameClassChecker라는 클래슨 내에 있는 변수는 public, protected, void, private 어디든 호출가능하다.
class SamePackageChecker extends Same {
public SamePackageChecker() {
//같은 패키지
Same same = new Same();
same._public();
same.protected();
same._default();
//same._private();
//같은 패키지 상속관계
this._public();
this._protected();
this._default();
//this._private();
}
}
위의 코드는 Same이라는 클래스를 인스턴스화 시키고 있다.
저 클래스는 SamePackage 안에 있다.
Same이라는 클래스를 상속했을 때 그 클래스내 메소드에 대해 같은 내용으로 정의한다. 왜냐하면 SamePackageChecker라는 클래스에서는 해당 메소드들을 정의한적 없기 때문이다.
그런데 위의 코드에서 확인했듯이 같은 패키지 내에서는 private의 제어자는 접근이 어렵다.
Class OtherPackageChecker extends Other {
public OtherPackageChecker() {
//다른 패키지
Other other = new Other();
other._public();
//other._protected();
//other._default();
//other._private();
//다른 패키지, 서브클래스
this._public();
this._protected();
//this._default();
//this._private();
Nothing nothing = new Nothing();
other._public();
//other._protected();
//other._default();
//other._private();
}
}
위의 코드는 다른 패키지에 있는 다른 클래스에 접근하는 사례를 보여준다.
여기서 만약 상속관계 없이 그냥 다른 패키지의 다른 클래스에 접근한다고 보았을때, public 제어자만 접근가능하다. 이는 맨 밑에 Nothing 클래스를 확인하면 알 수 있다.
그러나 Other클래스를 상속한다고 하면,public과 protected 제어자는 접근이 가능하다.