본문 바로가기

C++

[C++] 메소드 오버라이드(Override)

메소드 오버라이드란?

 

메소드 오버라이드는 객체 지향 프로그래밍에서 자식 클래스(파생 클래스)가 부모 크래스에 정의된 메소드를 재정의하는 것이다.

사전적 의미 : (직권을 이용하여 결정·명령 등을) 기각[무시]하다.(출처 : 네이버 사전)

 

메소드를 재정의하면 기존의 것이 무시된다.

 

#include <iostream>
using namespace std;

//부모 클래스
class PClass
{
public:
	int getNum() { return num; }
	
	void setNum(int param)
	{
		num = param;
	}

private:
	int num = 0;
};

//파생 클래스
class CClass : public PClass
{
public:
	void setNum(int param)
	{
		//num이 0과 10 사이값으로 유지되도록 기능추가
		//메소드 오버라이드
		if(param < 0) { PClass::setNum(0); }
		if (param > 10) { PClass::setNum(10); }
	}
};

int main()
{
	PClass a;	//부모 클래스 객체 생성
	a.setNum(-11);

	cout << a.getNum() << endl;

	CClass b;	//파생 클래스 객체 생성
	b.setNum(11);
	cout << b.getNum() << endl;

	return 0;
}

 

결과값:

-11
10

 

부모 클래스에서 setNum() 함수와 달리 파생 클래스에서 setNum() 함수는 0과 10의 범위를 유지하도록 메소드를 재정의하였다. 그 결과 부모 클래스 객체 a에서는 -11이라는 값이 그대로 출력되었고 파생 클래스 객체 b에서는 11이라는 값이 10으로 출력되었다. 이때 setNum()은 부모 클래스 setNum() 함수를 의미한다.

 

반면, 파생 클래스에서 부모 클래스의 소속이라는 소속 클래스를 명시하지 않으면 어떻게 될까?

 

//파생 클래스
class CClass : public PClass
{
public:
	void setNum(int param)
	{
	        //if(param < 0) { PClass::setNum(0); }
 		if(param < 0) { setNum(0); }

        	//if (param > 10) { PClass::setNum(10); }
		if (param > 10) { setNum(10); }
	}
};

 

결과값:

0

 

이때 setNum() 함수는 자기 자신의 setNum() 함수를 의미하여 재귀 호출된다. 즉, 11이라는 값을 매개변수로 받아 setNum(10); 코드로 자신의 setNum() 함수가 한 번 더 호출된다. 부모 클래스의 setNum()함수가 호출되지 않아 num값은 초기값 0이 출력된다. 즉, 대입하는 부모 클래스의 함수가 호출되지 않는다.

 

이처럼 메소드 호출할 때 소속 클래스를 명시해야 한다.

 

또한, 이러한 동작 과정을 보면 재정의한 이유는 기존 코드를 무시하거나 덮어쓰기보다는 기존 메소드와 새 메소드를 함께 작동하게 하려는 목적이 강하다.

 

int main()
{
	CClass b;	//파생 클래스 객체 생성
	b.setNum(11);	//묵시적 호출
        b.PClass::setNum(11);	//명시적 호출

	return 0;
}

 

위와 같이 묵시적 호출은 소속 클래스를 명시하지 않는 것이다. 자신의 클래스에서 setNum() 함수가 호출된다.

반면, 명시적 호출은 명시한 클래스의 함수가 호출된다.