캡슐화


우리는 이제까지 객체나 클래스의 변수나 메소드를 직접 접근하는 프로그래밍을 해왔습니다. 우리가 저질렀던 이런 방법의 프로그래밍은 조금 위험하다는 것을 알아야합니다. 


왜요?

모두가 접근 가능한 변수나 메소드는 제약 조건없이 쉽게 데이터가 변경 가능하기 때문입니다.

우리는 이 데이터가 안전하게 변경되기 위해서 포장, 또는 알맹이처럼 쌓아야하는 의무가 있습니다. 그게바로 객체지향에서 말하는 캡슐화라고 하는 것이죠.




어떻게 캡슐화가 이루어지는 지 상황을 통해서 알아보도록 합시다.


우리는 계좌의 5만원의 잔액을 갖고 있는 클래스 BankAccount가 있다고 칩시다. 간단하게 정의해보겠습니다.

 

class BankAccount{
	int balance=50000;
}


우리는 이 클래스의 객체로부터 인출하는 동작을 하고 싶다는 것입니다.

그럴때 외부에서 직접적으로 balance 변수에 접근하게 된다면 balance가 음수가 될 수도 있다는 겁니다. 인출은 절대 음수가 될 수 없다는 원칙을 깨고 원치않는 프로그램의 오류가 생기게 됩니다. 실제 이렇게 된다면 피해가 막심할 것입니다.


그러니, 우리는 데이터를 제어해야합니다. 

우선 balance라는 변수는 그 클래스 외부에서 절대 접근을 불가하게 만들고 알맞은 로직을 갖고 있는 멤버함수를 두어, 그 balance를 변경하게 만들면 되지 않을까요??


접근 제어자가 우리의 작은 소망을 들어 줄 수 있습니다.


접근지정자


그 전에 우리는 접근 지정자, 또는 접근 제한자라고 하는 녀석들부터 알아야합니다.


자바의 접근 지정자에는 4개가 있습니다. public, protected, default, private라는 녀석들이지요. 이 4개의 접근 지정자들은 멤버 변수나 멤버 메소드를 어떤 범위 내에서 접근하게 허락할 것인지를 정의하게 해줍니다.




다음의 표와 그림이 범위를 보여주고 있습니다. 


 접근 지정자

 오직 클래스

같은 패키지

 자식 클래스

 외부 어디서나

 public

 O

 O

 O

 O

 protected

 O

 O

 O

 

 default

 O

 O

 

 

 private

 O

 

 

 




public > protected > default > private 순으로 범위가 점점 좁아지는 것을 알 수 있습니다.


이 접근 제어자를 통해서 위의 코드의 문제점을 잡아보도록 하지요.


class BankAccount{
	private int balance=50000;
	
	public int withdraw(int m){
		if(balance<m)
			return 0;
		balance-=m;
		return m;
	}
}

변수는 private로 지정해서 BankAccount내에서만 제어가 가능하게 만들어 줍니다.


그리고 메소드를 통해서 m만큼의 돈을 인출하는 withdraw를 정의하는 겁니다. public 지정자로 withdraw메소드를 정의했으니, 누가나 withdraw를 호출할 수 있습니다. 또한, withdraw메소드는 BankAccount 멤버이기 때문에 balance라는 변수에 접근이 가능하며 이 메소드에서 제어를 하고 있습니다. 만일 인출하려는 금액 m이 지금 잔액(balance)보다 크다고 하면 0을 반환하는 것입니다. 그 외에는 그 금액을 인출하는 것이죠. 물론 잔액은 줄어들게 됩니다.


이렇게 원치않는 변경을 막기 위해 접근 지정자를 쓰게 된다면 balance를 보호할 수가 있습니다.


캡슐화가 이해되셨나요?




상속 관계만 데이터 접근 protected

우리는 상속관계에서 부모클래스의 데이터나 메소드를 자식 클래스만 접근을 허락해야 할 때도 있습니다. 이때 사용하는 지정자가 protected입니다.


example이라는 패키지에 두개의 클래스를 A, A를 상속받은 클래스 B를 정의합니다.


package example;
public class A{
	protected int a;
	public A(){}
}


package example;
public class B extends A{
	public B(){
		a=30;
	}
}


B는 A를 상속했으니 a에 대한 변수에 접근이 가능합니다.



같은 패키지의 main함수와 다른 패키지의 main에서 실험해보세요. 같은 패키지에서는 a에 접근이 가능하고, 다른 패키지에는 아래 그림에서 처럼 a가 proposals조차에서도 보이지 않습니다.




왜냐면 protected지정자로 지정된 변수나 메소드는 같은 패키지에서 모두 접근이 가능하기 때문이지요. 


우리는 다른 패키지에 있는 클래스 역시 상속을 할 수 있기 때문에 상속관계에서만 데이터 접근을 허락할 때는 protected 접근 지정자를 사용해야합니다.

반응형
블로그 이미지

REAKWON

와나진짜

,