말랑말랑제리스타일

오버라이딩과 오버로딩의 차이는?? 본문

프로그래밍/파이썬

오버라이딩과 오버로딩의 차이는??

제리제리 2022. 1. 6. 13:15

오버라이딩과 오버로딩은 명확히 다른 개념인데

이름이 비슷하다 보니까 종종 헷갈려 하시는 분들이 있더라구요

 

일단 메서드 오버로딩은 뭐냐?

매개변수의 타입(자료형) 또는 개수가 다르고 이름만 같은 함수를 말합니다

namespace overloading_and_overriding
{
    class Program
    {
        static void Main(string[] args)
        {
            print_hello(3);
            print_hello("HELLO");
            Console.WriteLine(print_hello(3,"hello"));
        }
        static void print_hello(int n)
        {
            for (int i = 0; i < n; i++)
            {
                Console.WriteLine("hello");
            }
        }

        static string print_hello(int n,string str)
        {
            string rtn = "";
            for (int i = 0; i < n; i++)
            {
                rtn += str;
            }
            return rtn;
        }

        static void print_hello(string str)
        {
            Console.WriteLine(str);
        }
    }
}

이런 코드를 봅시다

결과를 보면 서로 다른 세개의 메서드가 오버로딩을 통해 모두 호출된걸 알 수 있죠

 

가장 먼저 선언된 print_hello 함수는

static void print_hello(int n)

이렇게 int 형 매개변수 하나만 사용합니다

 

n을 3으로 넣어서 hello를 세번 출력한거고 리턴은 void니까 없죠

 

그런데 이런?? print_hello 라는 함수가 한번 더나오네요

근데 얘는 매개변수가 2개고 리턴형이 string이네요

static string print_hello(int n,string str)

이런 경우를 메서드 오버로딩이라고 합니다

이름이 같은데 매개변수와 리턴형은 다르죠?

그럼 매개변수는 같은데 리턴형은 다른 오버로딩은 가능할까요?

이건 기본적으로 C#에서 되지 않습니다

물론 가능한 언어가 있을 수 있지만 이게 왜 안되냐?

우리가 int로 리턴 받는다고 꼭 int형 변수에 저장해야된다는 규칙은 없거든요

void로 리턴하는 메서드인지 int로 리턴하는 메서드인지 C#은 구분을 못합니다

그래서 안됩니다

 

그래서 우리가 매개변수로 int형 하나와 string형 하나를 넣으면 이 두번째 print_hello 메서드가 동작하죠

 

그리고 세번째 print_hello가 등장합니다

static void print_hello(string str)

이녀석은 첫번째 메서드와 리턴형이 void로 동일하죠?

매개변수도 똑같이 한개입니다 

얘는 동작합니다

매개변수의 타입이 다르기 때문이죠

 

그렇다면 파이썬은 어떨까요?

def print_hello(i):
  print("hello")
  return
def print_hello(i,j):
  print("hellllllllo")
  return
print_hello(1)
print_hello(1,2)

자 이런식으로 매개변수가 하나인 것 두개인것 두개를 선언해봅니다

그리고 하나인 것 과 두개인 것을 호출해봅니다

그럼 에러가 떨어집니다

어디서요?

print_hello(1)에서요

왜냐 파이썬은 메서드 오버로딩이 기본적으로 없습니다

자료형이 워낙 유동적이기도 하고 인터프리터 언어 특성상 같은 이름의 메서드가 나오면 오버로딩이 아닌 새로 엎어버리거든요

그래서 두번째 메서드가 나올 때부터는 오버로딩이 아니라 첫번째 메서드를 사용할 수 없게 됩니다

 

여기까지가 오버로딩의 개념이었고!

 

오버라이딩은 상속 개념을 알아야합니다

상속이란 부모한테 메서드나 클래스 변수를 물려받는 개념입니다

    class Dog
    {
        string balk_sound;
        public Dog(string bs)
        {
            balk_sound = bs;
        }
        public virtual void balk()
        {
            Console.WriteLine(balk_sound);
        }
    }

    class BullDog : Dog
    {
        public BullDog(string bs):base(bs){

        }
        public override void balk()
        {
            Console.WriteLine("I'm bulldog");
        }
    }

    class Chiwawa : Dog
    {
        public Chiwawa(string bs)
            : base(bs)
        {
        }
    }

자 이렇게 Dog라는 클래스와 BullDog과 Chiwawa라는 두개의 자식 클래스가 있습니다

그리고 생성자를 물려주고

BullDog은 balk라는 메서드를 오버라이딩 했고 Chiwawa는 Overriding 하지 않았습니다

세마리를 객체로 만들고 짖어보겠습니다

여기서 자세히 볼게 오버로딩은 매개변수가 달랐지만 오버라이딩은 매개변수고 오리지날 메서드와 동일합니다

이게 핵심이죠

그리고 이 오버라이딩이 객체지향의 필수적인 개념이라고 하는만큼

객체지향을 지원하는 대부분의 언어(자바,C#,C++, 파이썬 등)는 이 오버라이딩만큼은 지원합니다

 

참고로 기본적으로 오버라이딩 할 메서드는 부모 메서드에 virtual로 처리를 해야하죠

그래서 virtual이 들어갑니다

    class Program
    {
        static void Main(string[] args)
        {
            Dog doggy = new Dog("BowWow");
            Chiwawa chiwawa = new Chiwawa("wokwok");
            BullDog bulldog = new BullDog("grrrrrrrrr");

            doggy.balk();
            chiwawa.balk();
            bulldog.balk();
            Console.ReadKey();
        }

    }

여튼 이렇게 해서 세마리 모두 짖어보면(실행시켜보면)

이렇게 오버라이딩 하지 않은 치와와는 개처럼 짖고

오버라이딩 한 불독은 나는 불독이야 라고 하죠

 

이게 바로 오버라이딩과 오버로딩의 개념입니다

 

가장 중요한건 바로 오버로딩은 매개변수가 원본 함수와 다르다, 오버라이딩은 매개변수가 원본 함수와 똑같다

이걸로 익혀두시면 안까먹을겁니다

Comments