오버로딩(Overloading) : 함수 중복 정의

오버로딩은 같은 이름의 함수에 매개변수를 다르게 사용하여 매개 변수에 따라 다른 함수가 실행되는 것.

 

오버라이딩(Overriding) : 함수 재정의

오버라이딩은 상속받았을때 부모클래스의 함수를 사용하지 않고 다른 기능을 실행할때 함수를 자식클래스에 같은 이름, 매개변수로 재정의 해서 사용하는것.

 

오버로딩 : 심화 설명

  • 메소드 이름이 같아야 한다.
  • 리턴형이 같아도 되고 달라도 된다.
  • 파라미터 개수가 달라야한다.
  • 파라미터 개수가 같을 경우, 자료형이 달라야 한다.

 

객체 지향 프로그래밍에서 오버로딩(Overloading)은 같은 이름의 메소드를 여러개 중복 선언하는 것을 말합니다.

C와 같은 기존언어에서는 같은 이름의 함수를 만들 수 없었습니다. 이것이 직관적으로 보일 수 있지만, 다음과 같은 경우를 보면 생각이 달라질 것입니다.

 

만약, 정수값들을 더해서 평균을 내는 메소드를 만들어서 사용하고 있다고 합시다. 이걸 사용하다 보니 같은 기능을 하는 것으로서 실수를 다루는 메소드를 만들고 싶다면 어떻게 할까요? 예를 들어, 정수를 위한 메소드 이름이 average()이었다면, 실수를 다루는 것은 조금이라도 이름이 달라야 하기 때문에 average_float()과 같은 식으로 작성해야 할 것입니다.

 

하지만, 이런식으로 메소드들이 수 없이 만들어지면 개발자는 모든 함수를 기억하기가 힘들어질 것입니다. 이 경우 둘다 평균을 구하는 것이기 때문에 average()라는 이름으로 사용하면 좋은것인데 말입니다. C#에서는 이런 경우 average()라는 이름을 같이 사용할 수 있도록 하고 있습니다.

즉, 정수를 인수로 받는 average()메소드와 실수를 인수로 받는 average() 메소드를 같이 정의할 수 있게 하는것입니다.

 

average() 루틴을 사용하는 측면에서 어떻게 각각을 구별할까요?

구별은 의외로 간단합니다. 단지, average() 메소드에 넘기는 인수의 종류를 달리해주면 됩니다. 정수를 다루는 average()를 부르고 싶다면, average() 인수에 정수값들만 넘기면 됩니다. 만약, 실수를 다루는 경우에는 average() 인수로 실수값들만 넘기면 내부적으로 적절한 메소드가 수행되도록 해줍니다.

 

/* 정수타입(1, 2, 3) 변수 a, b를 이용하여 평균값을 계산하는 함수 */
void average(int a, int b)
{
	int avg = 0;
	avg = (a * b) / 2;
    
	printf(정수값 %d와 %d의 평균은 %d 입니다.\n", a, b, avg);
}

 

/* 실수타입(1.5, 2.3, 3.1) 변수 a, b를 이용하여 평균값을 계산하는 함수 */
void average(float a, float b)
{
	float avg = 0;
	avg = (a * b) / 2;

	printf(실수값 %f와 %f의 평균은 %f 입니다.\n", a, b, avg);
}

 

훨씬 직관적인 프로그램을 할 수 있는 것입니다.

오버로딩을 위해서는 몇가지 지켜야 할 것이 있습니다. average()라는 똑같은 이름을 사용할 수 있다고 했지만, 각각을 구별할 수 있는 방법이 필요합니다. C#에서는 각 메소드에 대해서 시그네이쳐를 형성해서 이들을 구별합니다. 시그네이쳐는 각 메소드의 이름과 인수의 종류, 인수의 갯수에 구별됩니다.

따라서, 인수의 갯수나 타입만 다르다면 같은 이름의 메소드라도 몇개든지 선언할 수 있는 것입니다. 하지만, 반환타입은 시그네이처에 포함되지 않기 때문에 주의해야합니다. 반환값만 다른 경우에는 컴파일러가 에러를 발생시킬것입니다.

 

오버라이딩 : 심화 설명

  • 오버라이드 하고자 하는 메소드가 상위 클래스에 존재해야한다.
  • 메소드 이름이 같아야 한다.
  • 메소드 파라미터 개수, 파라미터의 자료형이 같아야 한다.
  • 메소드 리턴형이 같아야 한다.
  • 상위 메소드와 동일하거나 내용이 추가되어야 한다.

 

오버라이딩(Overriding)은 상속 관계간에 발생합니다. 기본적인 생각은 부모 클래스에 정의된 메소드와 똑같은 시그네이쳐를 갖는 메소드를 자식 클래스에서 정의해서 부모 클래스의 내용이 보이지 않게 하자는 것입니다.

이를 통해, 상속 받는 내용중 일부를 변경해서 사용하는 것이 가능해 집니다. 오버라이딩을 위해서는 부모 클래스에서 정의된 내용과 똑같은 이름과 인수 구성을 가져야 한다는 점을 명심하시기 바랍니다.

오버로딩의 경우에는 인수가 달라야 한다는 점을 빼면 특별히 해주어야 하는 부분이 없었습니다. 하지만 C#에서 오버라이딩을 구현하기 위해서는 virtual, override, new와 같은 몇가지 기능을 사용해야 합니다.

 

만약, 이러한 키워드를 사용하지 않은체로 프로그램을 컴파일할 경우 컴파일 되지않습니다.

 

#include <stdio.h>

class Parent
{
 public:
    void outA(int a)
    {
        printf("%d\n",a);
    }
};

    

class Child: public Parent
{
public:
    void outA(int a)
    {
        printf("%d\n",a+a);
    }
};


void main()
{
    Child a;
    Parent b;
    a.outA(10);
    b.outA(10);
}

'DevLog > C & C++' 카테고리의 다른 글

C++ 구조체(Struct)  (0) 2021.01.25
C++ STL 맵 기본 사용법과 예제  (0) 2021.01.24
C++ 가비지 컬렉션, 참조 카운트  (0) 2021.01.24
C++ 스마트포인터  (0) 2021.01.23
C++ 다형성과 가상함수  (0) 2021.01.22
복사했습니다!