이클립스에서 클래스를 만들면 public 이 따라온다.
main( ) 함수에도 항상 public 이 붙어 있다. 한번쯤 의문을 가져봤거나, 기분이 불편했다면 접근제어자에 대하여 들어볼 시간이다.
자바의 객체와 클래스라는 개념은 정보에 접근할 수 있는 제어를 필요로 한다.
이것을 실제의 세상과 비교해보는것이다.
예를 들어 자동차라는 객체와 개(DOG)라는 객체가 있다고 하자. 자동차의 메서드는 시동을 걸고 출발하는 것이다. 시동을 걸고 출발하기 위해서는 차의 주인이 키를 들고 와야 한다. 자동차를 움직이는 가장 올바른 방법이다. 그런데 갑자기 개(DOG) 객체가 자동차의 문을 열고 시동을 건다. 상상이 안되는 이야기지만, 방금 상상했다. 프로그래밍의 세계에는 개도 고양이도 운전할 수 있다.
가상현실에서 개가 운전하도록 프로그래밍을 작성하는 것은 자유지만 현실세계에서 그러면 큰일이다. 물론 가상세계에도 나름의 법이 있다. 여기서 접근 제어자가 필요하다.
자바는 클래스 내부의 멤버 변수나 메서드, 생성자에 대하여 접근을 제한 할 수 있다. 지금까지 봤던 public 도 접근 제어자의 하나이다. 접근 제어자는
1) public
2) protected
3) private
4) 아무것도 없는 경우
네 가지가 있다. 이들은 자바의 예약어 이다. 클래스, 멤버변수, 메서드 앞에 사용한다.
1) public
public (공개의, 공유의, 공공의~ 뜻) 즉 어디서나 접근이 가능하다. 자바가상머신(JVM)이 자바 프로그램을 시작할 때 적어도 한개의 클래스는 public이어야 한다. main 함수가 public 인 이유도 마찬가지다. JVM 이 클래스를 로드하여 시작하려는 지점이 main 함수니까 public 이어야 한다.
2) protected
protected (보호되는~ 뜻) 같은 패키지에서 사용할 수 있다. 같은 패키지의 상속을 받은 클래스에서도 사용할 수 있다. 다른 패키지라도 상속을 받았으면 사용할 수 있다. protected는 상속관계 내용에서 들여다 봐야 한다. 이 문서는 public 과 private이라도 구분하는 것에 포커스를 둔다.
3) private
private(개인의,사유의,전용의 뜻) 같은 클래스 안에서만 접근을 할 수 있다. A 클래스와 B 클래스가 같은 패키지안에 있다면 A 클래스의 private 변수와 메서드는 B 클래스에서 접근이 불가능하다. public 에 대비되는게 private 이다. 원래 영어 단어도 공적인 것이 public 이고 사적인 것이 private 이다.
객체의 프라이버씨(Privacy)를 지켜주는 것이 중요하다고 생각하는 것이 객체 지향 프로그래밍의 중요한 특징이다.
이렇게 멤버 변수와 메서드를 외부에서 접근하지 못하도록(not visible) 하는 것을 정보의 숨김 (information hiding) 이라 하며 접근 제어자를 사용해서 캡슐화(Encapsulation) 를 한다.
*캡슐화(Encapsulation)
- to provide an interface for (a piece of software or hardware) to allow or simplify access for the user
유저에게 접근을 허용하거나 단순화 시키기 위해서 소프트웨어나 하드웨어에게 인터페이스를 제공하는 것
이라 하는데 캡슐안에 다 넣는 것 처럼 객체를 보호하고 확실한 인터페이스만 제공해서, 클래스를 사용하는 유저들이 안심하고 사용할 수 있다느 말이다.
OOP에 대해서는 워낙 좋은 글들이 많이 있다. (특히 영문으로) 캡슐화에 대하여 더 깊이 알고 싶은 분들은 스떼키파이를 참고하시길 권한다.
https://stackify.com/oop-concept-for-beginners-what-is-encapsulation/
4) 아무것도 없는 경우 (default)
접근 제어자가 없는 경우 default 라고 하며 같은 패키지안에서만 접근이 가능하다. private 보다는 넓다.
이 표에서 보는 것 처럼
private >> default >> protected >> public
으로 접근 할 수 있는 범위가 넓다.
이 단원까지 순차적으로 왔다면, 그 동안에 의식하지 않았지만 public 을 사용한 것이다. 딱히 신경쓸 것이 없었다. 거의 어디에서나 사용이 가능하다. 사실 문자열을 처리하기 위한 String 클래스도 public 이다. public 이어야지 모든 자바 클래스에서 접근이 가능하니까 당연하다.
그래서 예제는 private 을 사용해본다. getter 와 setter 를 사용해서 private 변수들을 조작할 것이다.
<예제>
* 객체는 NBA 선수이다. 변수를 다 private 으로 하면 이제 NBAPlayer 라는 클래스 바깥에서는 접근이 불가능하다. 대신 메서드 getter와 setter 를 사용해서 조작한다. getter 는 가져오는 메서드, setter 는 세팅하는 메서드. getter는 리턴값이 있고, setter 는 매개변수를 받는다. this.name 은 private String name 을 말한다. 매개변수와 이름이 같아도 다른 것이다.
public class NBAPlayer {
private String name;
private int age;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
public class PlayerTest {
public static void main(String[] args){
NBAPlayer p1 = new NBAPlayer();
p1.setName("Lebron James");
System.out.println(p1.getName());
}
}
PlayerTest 클래스의 main 함수에서 NBAPlayer 의 인스턴스를 생성한다.
p1.name = "Lebron James" 이렇게 접근하면 컴파일 오류가 난다. private 멤버 변수인 name은 내부에서만 접근할 수 있다. 대신 setter 로 멤버변수를 조작하고 getter로 저장된 값을 얻어 올 수 있다.
접근제어자가 4개나 되서 복잡해 보이지만 private과 public 의 차이를 아는데서 시작하면 간단하다. 참고로 이클립스에는 클릭 몇번으로 getter 와 setter를 생성해주는 기능이 있으니 잘 활용하자. 작업폴더에서 클래스를 우클릭하여 source -> Generate getter and setter 에 들어가서 멤버변수들을 체크박스하고 완료를 누르면 바로 자동으로 코드가 작성된다.
이클립스의 기능들을 잘 쓰면 객체 지향 프로그래밍이 더 재미있어 진다.