※ Chapter09 정보 은닉 그리고 캡슐화.
※ 본문은 윤성우의 열혈JAVA를 정리한 글입니다.
※ 문제가 될시 비공개 처리하겠습니다.
§정보 은닉(Information Hiding)
자바에서 말하는 '정보'는 클래스의 '인스턴스 변수'를 의미한다
■ 정보를 은닉해야 하는 이유
예제를 보자.
위의 메소드 중 setRad(double r) 정의를 통해서 Circle 클래스를 정의한
이의 다음 의도를 읽을 수 있다.
"반지름의 길이 rad에 0보다 작은 값이 저장되는 일이 발생하지 않도록 하겠다."
반지름의 길이를 변경할 때는 반드시 위으 메소드 호출을 통해 변경을 진행해야 한다.
따라서, 클래스 사용자가 잘못된 값을 인스턴스 변수에 저장하지 않도록
위와 같은 유형의 메소드를 제공해야 한다.
위의 예제에서는 프로그램 사용자의 실수로 다음과 같은 접근이 발생하였다.
c.rad = -4.5;
인스턴스 변수의 직접적인 접근을 허용하면, 컴파일 과정에서 드러나지 않는 중대한 실수가
발생할 수 있다.
위와 같은 접근을 허용하지 않도록 클래스를 설계하는 것을 '정보 은닉' 이라고 한다.
■ 정보의 은닉을 위한 private 선언
'정보를 은닉하는 방법'은 어렵지 않다.
인스턴스 변수의 앞에 private 선언을 한다. 그리고 해당 인스턴스 변수에 접근할 수 있는
메소드를 별도로 제공하면 '정보 은닉'이 완료된다.
예제를 보자.
클래스의 Circle의 다음 인스턴스 변수가 private으로 선언이 되었다.
private double rad = 0; // 클래스 내부 접근만 허용
이것이 의미하는 바는 "변수 rad는 클래스 내부에서만 접근을 허용하겠다." 이다.
만일 main에서 다른 class에 선언된 변수를 접근할 경우 컴파일 오류가 발생한다.
인스턴스 변수 rad를 private로 선언했으니, setRad와 getRad의 제공이 필요하다.
값의 참조를 위한 메소드는 게터(Getter)이고, 값의 설정를 위한 메소드는 세터(Setter)이다.
▶게터(Getter)
- 인스턴스 변수의 값을 참조하는 용도로 정의된 메소드
- 변수의 이름이 name일 때, 메소드의 이름은 getName으로 짓는 것이 관례
▶세터(Setter)
- 인스턴스 변수의 값을 설정하는 용도로 정의된 메소드
- 변수의 이름이 name일 떄, 메소드의 이름은 setName으로 짓는 것이 관례
§접근 수준 지시자(Access-level Modifiers)
private 선언과 같은 것을 '접근 수준 지시자'라고 한다.
■ 4가지 종류의 '접근 수준 지시자'
public, protected, private, default
(default는 선언하지 않은 상황을 의미함)
클래스의 정의 대상 : public, default
인스턴스 변수와 메소드 대상 : public, protected, private, default
■ 클래스 정의 대상의 public과 default 선언이 갖는 의미
public class AAA { } // 클래스의 public 선언
class BBB {} // 클래스의 default 선언
차이점은 다음과 같다.
public - 어디서든 인스턴스 생성이 가능하다
default - 동일 패키지로 묶인 클래스 내에서만 인스턴스 생성을 허용한다.
클래스의 public 선언과 관련하여 다음 두 가지 사항을 지켜야 한다.
- 하나의 소스파일에 하나의 클래스만 public으로 선언한다.
- 소스파일의 이름과 public으로 선언된 클래스의 이름을 일치시킨다.
다음 예제를 보면서 확인하고 넘어가자
package zoo;
class Duck {} //default 선언이므로 동일 패키지 내에서만 인스턴스 생성 가능
public class Cat { //public 선언이므로 어디서든 인스턴스 생성 가능 public void makeCat() { Duck quack = new Duck(); // 동일 패키지이므로 생성 가능 } } |
package animal;
public class Dog { public void makeCat() { zoo.Cat yaong = new zoo Cat(); //Cat은 public 선언이므로 어디서든 생성 가능 }
public void make Duck() { zoo.Duck quack = new zoo.Duck(); // Duck은 default 선언이므로 여기서는 컴파일 오류 발생함. } } |
■ 인스턴스 멤버 대상의 public, protected, private, default 선언
class AAA {
public int num1;
protected int num2;
private int num3;
int num4;
public void md1() {}
protected void md2() {}
private void md3() {}
void md4() {}
}
여기서 public 선언과 default 선언이 갖는 의미는 앞에서 설명한 것과 같다.
따라서, private 선언과 protected 선언이 갖는 의미를 살펴보자.
■ 인스턴스 멤버의 private 선언이 갖는 의미
'정보 은닉'을 설명하면서 private선언의 기능과 그 의미는 이미 알고 있다.
하나의 예를 보면서 마무리 하자
class Duck {
private int numLeg = 2; //클래스 내부에서만 접근 가능
public void md1() {
System.out.println(numLeg); //접근 가능
md2(); // 호출 가능
}
private void md2() {
System.out.pritnln(numLeg); //접근 가능
}
void md3() {
System.out.println(numLeg); //접근 가능
md2(); //호출 가능
}
}
■ 인스턴스 멤버의 protected 선언이 갖는 의미
default 선언과 비교해서 이해하면 빠르다.
"protected 선언은 default 선언이 허용하는 접근을 모두 허용한다."
"더불어 protected는 default가 허용하지 않는 '한 영역'에서의 접근도 허용한다."
'한 영역'을 이해하기 위해서는 상속이라는 개념을 알아야 하지만 간단하게 학습하고 넘어가자.
public class AAA {
int num;
}
-----------------------
public class ZZZ extends AAA { // extends AAA는 클래스의 상속을 의미함
public void init(int n) {
num = n;
}
}
ZZZ클래스가 AAA클래스를 상속했기 때문에 num의 접근이 가능한 것이다.
이 상황에서 두 클래스가 서로 다른 패키지로 묶여있는 다음과 같은 상황을 보자.
package alpha;
public class AAA {
int num;
}
-----------------------
public class ZZZ extends alpha.AAA { // AAA가 alpha 패키지로 묶였으므로 이렇게 됨.
public void init(int n) {
num = n;
}
}
이 상황에서 밑에 코드는 오류가 발생한다.
default에서는 허용하지 않기 때문이다. 이같은 상황에서 바로 protected를 사용한다.
package alpha;
public class AAA {
protected int num;
}
-----------------------
public class ZZZ extends alpha.AAA { // AAA가 alpha 패키지로 묶였으므로 이렇게 됨.
public void init(int n) {
num = n;
}
}
이렇게 되었을때에는 정상적으로 컴파일이 완료된다.
"protected로 선언된 멤버는 상속 관계에 있는 다른 클래스에서 접근 가능하다."
이제 표로 정리한 것을 보면서 마무리하자.
지시자 | 클래스 내부 | 동일 패키지 | 상속 받은 클래스 | 이외의 영역 |
private | O | X | X | X |
default | O | O | X | X |
protected | O | O | O | X |
public | O | O | O | O |
접근 허용 범위에 대해 간단하게 생각하려면 다음과 같이 생각하자
public > protected > default > private
'JAVA' 카테고리의 다른 글
자바 기초부터 차근차근...(11) (0) | 2020.04.25 |
---|---|
자바 기초부터 차근차근...(10) (0) | 2020.04.24 |
자바 기초부터 차근차근...(8) (0) | 2020.04.22 |
자바 기초부터 차근차근...(7) (0) | 2020.04.21 |
자바 기초부터 차근차근...(6) (0) | 2020.04.21 |