안녕하세요? 환민입니다.
오늘은 제가 "왜 이럴까?" 하고 의문을 품었던 부분에 대해 얘기를 하려고 합니다.
지금은 해결이 되었지만, 예전에 친구 만나고 집에 오는 전철 역에서 곰곰이 생각했던
기억이 아직도 생생한 문제입니다. ^^
머냐하면... 클래스에 멤버 변수를 접근함에 있어서, 그냥 멤버 변수를 public에 두고
접근하면 되지, 왜 귀찮게 Get, Set 함수를 둬야 하는가? 라는 문제입니다.
좀더 자세히 말하자면, 멤버 변수를 클래스의 private 영역에 두고, Get, Set으로 시작되는
이름을 갖는 (머.. 꼭 그래야 하는건 아니고.. 관습이죠) 멤버 함수를 통해서
그 private 멤버 변수에 값을 대입하고, 값을 얻어오는 것을 말합니다.
예)
class MyClass
{
private:
int m_Age; // 나이
public:
void SetAge(int pAge)
{
m_Age = pAge;
}
int GetAge()
{
retrun m_Age;
}
};
이렇게 하면 그냥 간단히 해도 되는게 좀 복잡해지는 경향이 있습니다.
복잡한걸 왜 해야 하나? 특별한 이유를 모를 수 있습니다.
그래서 그 이유에 대해 설명하고자 이 글을 씁니다.
결론부터 말하자면, 아래와 같은 이유 때문에 Get, Set 멤버함수를 두는 방법을
사용하는 것을 적극 권장한다는 것입니다!
일단, 멤버 변수에 접근한다는 사실을 객체가 알 수 있습니다.
이게 무슨 말인가 하면...
Get, Set 이라는 멤버 함수를 호출하기 때문에 클래스 입장에서는 아...
어떤 넘이 내 Get, Set 함수를 호출해서 내 멤버변수의 값을 읽어오고, 넣어주고
하는 구나... 를 알고, 그러한 값을 읽어오고, 넣어주는 과정에 개입할 수
있습니다.
int MyClass::GetAge()
{
return m_Age;
}
원래는 이렇습니다.
GetAge를 호출하면 바로 저 멤버함수가 호출되므로, 저 멤버함수 안에
어떠한 처리를 함으로서, 위에 말했던 '개입'을 할 수 있습니다.
예를 들어, MyClass 객체가.. 히히 나이 속여야지~~~~ 라고 한다면
다음과 같이 할 수 있습니다.
int MyClass::GetAge()
{
// 가짜 나이를 리턴한다.
return 2;
// return m_Age;
}
저러면 클래스를 이용하는 입장에서는 무조건 클래스가 2살짜리 애인 줄 알게 됩니다.
아니면 다음과 같이 (가장 흔한 형태입니다.) 값을 대입할 때, 유효성 검사를 할 수 있습니다.
void MyClass::SetAge(int pAge)
{
if (pAge >= 1 || pAge <= 150) // 당연히 1살 이상이여야 하고, 150살 넘어까지 못산다고 하면...
{
m_Age = pAge;
}
else
{
유효한 범위를 넘었다는 예외를 발생시킨다!
}
}
또한 이런 예도 있을 수 있습니다.
클라이언트가 내 클래스에서 변수 몇번 읽어 갔나를 셀 수도 있죠.
int MyClass::GetAge()
{
GetAgeCount++;
return m_Age;
}
이렇듯이, 클래스의 멤버 변수의 값을 읽어가고, 값을 넣어줄 때,
그 것에 대해 클래스가 개입해서 어떤 동작을 취해 줄 수 있다는 것입니다.
이러한 이유 때문에 사용하고, 당장은 아무런 동작을 취해주지 않는다고 해도
위와 같이 작성해 놓는 것이 나중을 위해 필요합니다.
int AgeValue = MyClassObject.Age;
이런 식으로 Age를 public 멤버 변수로 두고 얻어 간다면,
클래스 입장에서는 Age 값을 얻어 갔는지 알 방법이 없습니다.
그러니 좀 이론적인 설명으로... 멤버 변수에 접근한다는 사실을 객체가 알 수 있다.. 라고
설명합니다.
그리고 또한 중요한 사실은, '인터페이스(interface)' 와 관련되어 꼭 사용되어야
한다는 것입니다.
인터페이스에 대해 자세히 설명하자면, 글 자체가 많이 길어지므로 생략하고요.
간단히 설명드리면, 클래스의 'public 멤버 함수'의 집합이라고 생각하시면 됩니다.
그러니 Age라는 public 멤버 변수를 둔다한들 인터페이스 안에는 끼지 못하죠.
그러나 계속 얘기한 Get, Set 방식을 이용하면 인터페이스에 낄 수 있습니다.
Get, Set 함수를 'Accessor 함수'라고 합니다. 한국말로 하면 '접근자' 지요.
또한, 이러한 Get, Set 함수의 필요성에 새로운 언어들에서는 언어적 측면에서
직접적으로 이러한 기능을 지원해 줍니다.
델파이와 C#, 비주얼 베이직, 씨빌더(C++언어를 사용하지만 확장된 기능으로서 지원)
등에서 '프로퍼티(property)'라는 언어적 기능으로서 이러한 '접근자'를
제공합니다.
얼마나 자주 쓰이고 필요했으면, 언어 차원에서 지원을 하겠습니까?
이유가 충분히 공감이 가신다면, 아마 이미 그렇게 사용하고 계실 것이고,
그렇지 않다면, 충분히 생각해 보시고요.. 일단은 공감가지 않으시더라도
위와 같은 규칙을 100% 따라 주는게 좋다라고 말씀드립니다.
행복하세요.
|
좋은 글 감사합니다.
이런 객체지향에 대한 원론적인 글이 많았으면 좋겠어요~