Language/Java

정보 은닉(Information Hidding)

Hoplin 2019. 2. 20. 03:35
반응형

자바에서의 '정보'란 '인스턴스 변수'를 의미한다. 현재 포스팅의 제목의 정보 은닉을 다시 해석해 보면 즉 인스턴스 변수 은닉이라고 재 해석할 수 있는데, 그러면 왜 우리가 이 '정보'라는 것을 숨겨야 하는 것일까? 간단한 예제코드를 해석해 보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//흔히 자바에서 말하는 '정보' 는 인스턴스 변수를 의미한다.
class Circle {
    final double pi = 3.14;
    int rad = 0;
    public Circle(int r)
    {
        rad = r;
        setrad(r);
    }
    public void setrad(int r)
    {
        if(r < 0)
        {
            rad = 0;
            return;
        }
        rad = r;
    }
    public double getArea()
    {
        return (rad * rad) * pi;
    }
}
 
class circle1{
    public static void main(String args[])
    {
        Circle ex = new Circle(10);
        System.out.println(ex.getArea());
        
        ex.setrad(5);
        System.out.println(ex.getArea());
        
        ex.setrad(-3);
        System.out.println(ex.getArea());
        
        
        ex.rad = -4;// setrad 메소드를 통해서 값을 변경해 주어야 하는데  바로 인스턴스 변수로 직접적인 접근을 허용하게되면 컴파일 과정에서 드러나지 않는 중대한 실수가 발생할 수 있다.
        //문제가 발생하지 않도록 클래스를 설계할 필요가 있다. 그러한 클래스 설계를 정보 은닉이라고 우리는 말한다.
        System.out.println(ex.getArea());
        
    }
}
 
cs


해당 코드는 원의 넓이를 구하고 새로운 원의 반지름을 입력하되, 음수일 경우 반지름을 의미하는 인스턴스 변수에 값을 0을 넣는것을 수행하는 코드이다. 이 코드에서 이상한 점을 찾아보자. 해당 질문의 정답은 ex.rad = -4라는 부분이다. 해당 코드는 정상적으로 작동하는데, 한번 ex.rad = -4와 그 밑의 표준 출력문의 결과값이 무엇일지 생각해보자. 우선 해당 코드의 결과값을 보자.



네번째 50.24가 ex.rad = -4라는 출력값의 결과인데, 물론 rad라는 인스턴스 변수에 -4를 넣고 -4 * -4 * 3.14를 해서 50.24나온게 맞다고 생각하는 사람이 있을 수 있다. 하지만 해당 코드를 작성한 사람은 반지름의 입력값이 음수일 경우 인스턴스 변수 rad에 0을 대입하겠다고 메소드를 정의해 두었다. 이는 즉 코드를 작성한 사람의 의도에서 '오류'인 것이다. 하지만 이 오류는 겉으로(코드에서)는 보여지지 않는다. 즉 이와 같은 인스턴스 변수에 대한 직접적인 접근은 겉으로도 매우 치명적인 오류를 만들 수 도 있지만 컴파일 과정에서도 잠재적으로 치명적 오류가 발생할 수 도 있는 것이다. 그렇기에 우리는 인스턴스 변수에 접근할 수 없도록 클래스를 설계해 주어야 하는것이며, 그러한 클래스 설계를 '정보 은닉'(Information Hidding)이라고 하는것이다.


그렇다면 정보 은닉은 어떻게 해야하는 것일까? 정보 은닉은 매우 간단하다. 순서는 다음과 같다.


1 . 인스턴스 변수 앞에 'private'선언을 해준다

2 . 인스턴스 변수에 접근할 수 있는 메소드를 별도로 제공한다


이 두가지 과정을 거치면 정보 은닉이 된다. 그러면 위의 코드에서 정보 은닉을 한 후의 코드를 살펴보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class InfoHid2 {
    private double rad = 0;//private선언을 해주고 나서 인스턴스 변수에 접근할 수 있는 메소드를 제공하면(여기에서는 setrad()) 정보은닉이 완료된다.
    //해당 문을 해석해보면 변수 rad는 InfoHid2라는 클래스 내부에서만 접근하는것을 허용하겠다는 의미이다.
    final double pi = 3.14;
    
    public InfoHid2(double ra)
    {
        setrad(ra);
    }
    public void setrad(double a)//값의 설정을 위한 메소드. 이렇게 값을 설정하기 위해서 만드는 메소드를 세터(Setter)라고 한다. 인스턴스 변수의 값을 설정하는 용도로 정의된 메소드이다. 주로 앞에 set을 붙인다.
    {
        if(a < 0)
        {
            rad = 0;
            return;
        }
        rad = a;
    }
    public double getRad() {//값의 접근을 위한 메소드. 이렇게 인스턴스 변수의 값을 참조하기 위해 만드는 메소드를 게터(getter)라고한다. 인스턴스 변수 값을 참조한다. 주로 앞에 get을 붙인다.
        return rad;
    }
    public double all()
    {
        return (rad * rad) * pi;
    }
}
 
class circle
{
    public static void main(String args[]) {
        InfoHid2 a = new InfoHid2(3.7);
        System.out.println("반지름 : " + a.getRad());
        System.out.println("전체 넓이 :" + a.all());
        
        a.setrad(4.2);
        System.out.println("반지름 : " + a.getRad());
        System.out.println("전체 넓이 :"  + a.all());
        
        //a.rad = 3.3; 주석을 없애면 오류가 나는것을 볼 수 있다.
    }
}
 
cs


해당 코드에서 보면 private double rad = 0 이라는 코드를 사용하였다. 해당 코드를 해석해 보자면 


'double형 rad인스턴스 변수는 해당 변수가 선언된 클래스 내부에서의 접근만 허용한다' 


라는 의미로 해석하면 된다. 위 코드의 39번쨰 줄에 써놨듯이 a.rad()라는 형식으로 인스턴스 변수에 접근하면 오류가 나는것을 볼 수 있다. private를 선언한 인스턴스 변수에 대해서는 두가지 형태의 메소드가 존재한다 하나는 게터(getter)라는 메소드고 하나는 세터(setter)라는 메소드이다. 위의 코드에서는 setrad가 세터, getrad가 게터가 된다. 세터와 게터의 각각의 특징은 다음과 같다.


*세터(Setter)

- 값의 설정을 위한 메소드이다.

- 주로 setter역할을 하는 메소드 앞에 set이라는 수식어를 붙여준다

- 해당 코드에서는 setrad라는 메소드를 통해서 인스턴스 변수 rad의 값을 설정해 주었다


* 게터(Getter)

- 주로 인스턴스 변수 값의 참조를 위해서 많이 정의된다.

- 주로 getter역할을 하는 메소드 앞에 get이라는 수식어를 붙여준다

- 해당 코드에서는 getrad라는 메소드를 통해서 인스턴스 변수값을 참조하였다.

반응형