접근 제어자는 클래스의 멤버(변수, 메소드)들의 접근 권한을 지정한다.
class A {
public String y(){
return "public void y()";
}
private String z(){
return "public void z()가 실행됨";
}
public String x(){
return z();
}
}
public class accessCt {
public static void main(String[] args) {
A a = new A();
System.out.println(a.y());
// 아래 코드는 오류가 발생한다.
//System.out.println(a.z());
System.out.println(a.x());
}
}
우선 System.out.println(a.y());
와 System.out.println(a.x());
는 실행된다 하지만 System.out.println(a.z());
는 오류가 발생한다. 왜 메소드z만 실행되지 않을까?
그 이후는 메소드z 정의 시 가장 앞에 붙어있는 private
때문이다.
private
자리에 오는 것들을 접근 제어자(acess modifier)라고 한다. 이는 클래스 (A) 밖에서는 접근할 수 없음을 의미하는데, 보통 내부적으로 사용하기 위해서 이 private
을 이용한다.
반면, 클래스A의 메소드x는 접근 제어자가 public
이기 때문에 호출이 가능하다. 또한 메소드z와 메소드x는 같은 클래스 소속인데, 내부적으로 메소드z를 호출하고 있으므로 z가 정상적으로 호출된다.
접근 제어자는 왜 사용하는 것일까?
1. 사용자가 객체를 사용할 때, 객체 내부적으로 사용하는 변수나 메소드에 접근함으로써 개발자가 의도하지 못한 오동작을 일으킬 수 있기 때문
2. 사용자에게 객체를 조작할 수 있는 수단만을 제공함으로서, 객체 사용에 집중할 수 있도록 돕기 위함임
앞의 다른 포스트들에서 이용한 계산기 예제에서 접근 제어자를 이용해보자.
매개변수를 통해 값을 입력받는 left
와 right
값은 인스턴스 필드로, 객체 외부에서 호출될 필요가 없다. 때문에 외부로부터 이 변수를 숨기기 위해 다음과 같이 선언할 수 있다.
private int left, right;
내부적으로 처리될 수 있는 계산들은 private
을 이용해서 내부적으로 처리하고, 결과만 외부에 출력해주는 것이 좋다. 이렇게 하면 사용자가 접근해서는 안되거나, 접근할 필요가 없는 멤버에 대한 접근을 통제할 수 있다.
protected는 상속 관계에 있다면 서로 다른 패키지에 있는 클래스 접근도 허용해주는 접근 제어자이다. default는 접근 제어 지시자가 없는 경우를 의미하는데, 접근 제어자가 없는 메소드는 같은 패키지에 있고 상속 관계에 있는 메소드에 대해서만 접근을 허용한다.
클래스에도 2가지 접근 제어자가 있다. 클래스의 접근 제어자는 패키지와 관련된 개념이다.
- public : 다른 패키지의 클래스에서도 사용할 수 있음
- default : 접근 제어자를 붙이지 않은 경우로, 같은 패키지에서만 사용 가능함
두 개의 클래스를 만들고, 이 클래스들과 같은 패키지에서 2개의 클래스들을 이용해보자.
// public_class.java
package src.java.inner;
public class public_class{}
// default_class.java
package src.java.inner;
class default_class{}
// 같은 패키지 내에 있는 다른 클래스에서 public_class와 default_class 이용해보기
package src.java.inner;
public class classAccessPack{
public_class publicClass = new public_class();
// default_calss defaultCalss = new default_class();
}
default_calss defaultCalss = new default_class();
에서 Error가 발생한다. default_class
의 접근 제어자가 default
이기 때문이다.
하나의 소스코드에는 하나의 public 클래스가 존재할 수 있다.
즉, public 클래스가 포함된 소스코드는 public 클래스의 클래스 명, 소스코드의 파일 명이 같아야 한다.
Reference
1. 접근 제어자