본문으로 바로가기

오버로딩(Overloading)

일반적으로 하나의 클래스 안에 정의된 메서드들의 이름은 중복될 수 없습니다

그러나 오버로딩 기법을 이용하면 하나의 클래스에 같은 이름을 가진 메서드를 여러 개

정의할 수 있습니다. 전 장에서 했던 내용이지요,

다만 메서드의 이름은 같되 매개변수의 정보(개수 및 타입)는 달라야 합니다

메서드의 이름과 입력 매개변수의 정보(개수 및 타입)를 메서드의 시그너처라고 합니다

(메서드 시그너처(Signature): 메서드 이름 + 매개변수 정보(개수 및 타입 정보))

한 클래스에 정의된 메서드들은 모두 시그너처 정보가 유일해야 합니다

즉 메서드의 시그너처를 유일하게 한다면 메서드의 이름은 얼마든지 같을 수 있는 것입니다

오버로딩은 이미 정의된 메서드와 이름은 같지만 시그너처는 다르기 때문에 가능한 것입니다.

다음 코드는 하나의 클래스의 동일한 이름의 메서드(그러나 시그너처는 다른)가 정의된 모습입니다

public class A
{

   public int Hello(){

   return 0;

   }

   public int Hello(int i){

   return i;

   }

}


오버로딩은 왜 사용하나
?
동일하거나 유사한 일을 수행하는 메서드가, 전달 받는 매개변수에 따라 조금씩 다른 연산을 해야 하는 경우에 모든 상황에 따라 메서드 이름을 각각 정의 하는 것보다 매개변수 정보만 달리하여 동일한 이름으로 정의한다면 코드를 작성하는 입장에서나 사용하는 입장에서 직관적이고 편리하게 사용할 수 있을 것입니다.

닷넷라이브러리에서도 이러한 예를 찾아볼수가 있습니다.

우리가 콘솔환경에서 상당히 많이 쓰는 Console.WriteLine();메서드가 대표적입니다.

Console.WriteLine([int type]);

Console.WriteLine([bool type]);

Console.WriteLine([double type]);

Console.WriteLine([string type]);

Console.WriteLine([object type]);

등등...이 Console.WriteLine()메서드는 못하는 출력이 없습니다.

이와같은 오버로딩기법으로 인해서 편리하고 직관적인 프로그래밍이 가능합니다.

물론 상세한 설정을 원하면 얼마든지 가능하구요

마치 프로그램 설치 시 기본 설정과 상세(사용자 정의) 설정이 있는 것과 유사해 보입니다

만약 오버로딩이 없다면...매개변수가 더 많을 경우에는 더 복잡해 지겠죠

상상도 하기 싫습니다. 저 많은 콘솔.WriteLine()메서드의 종류를 다 외워야겠지요?

아래의 예는 큰 수를 반환하는 메서드를 전달받는 매개변수의 수에 따라 오버로딩 한 예시입니다

public class A
{

   public static int Max(int i, int j){

   return i > j ? i : j; //둘 중 큰수를 반환한다

   }

   public static int Max(int i, int j, int k){

   return Max(Max(i, j), k); //Max(int, int) 를 호출한다

   }

   public static int Max(int i, int j, int k, int l){

   return Max(Max(i, j, k), l); //Max(int, int, int) 를 호출한다

   }

   public static int Max(int[] arrays){

   int maxValue = 0;

   foreach (int i in arrays){

   maxValue = Max(maxValue, i); //Max(int,int) 를 호출한다

   }

   return maxValue;

   }

}


오버라이딩
(Overriding)

오버로딩(Overloading)은 한 클래스 내에서 동일한 이름의 메서드를 추가 정의하는 것인 반면,

오버라이딩(Overriding)클래스간 상속 관계에서 메서드를 재 정의하는 기법입니다

전장에서 간략하게 소개를 드렸습니다.

두 클래스가 상속 관계에 있으면 부모 클래스의 public, protected 으로 선언된 메서드는 자식 클래스로 그대로 상속되어 자식클래스에서 사용이 가능하게 됩니다.

즉 이미 정의된 메서드를 재 사용하게 되는 것이죠

단순히 재 사용을 하지 않고 자식 클래스에서 상속 받은 메서드를 재 정의하여

다른 연산을 수행하도록 하는 것이 오버라이딩 입니다.

즉 자식 클래스에서 부모 클래스의 특정 메서드를 다시 정의하게 됩니다

오버라이딩은 오버로딩과는 달리 메서드의 이름이 동일해야 합니다

그리고 virtual override 키워드를 사용하여 오버라이딩을 구현하게 됩니다

virtual override 키워드

class Parent
{

   public virtual void Parent(){

   Console.WriteLine("부모 메서드");

   }

}

class Child : Parent{}

   static void Main()

   {

      Child child = new Child();

      child.Parent(); //"부모메서드" 가 출력 됨

   }

이때 부모 클래스의 ParentMethod를 자식 클래스에서는 다르게 구현 하고 싶을 경우

오버라이딩 하면 됩니다

class Child : Parent

{

   public override void Parent(){

   Console.WriteLine("자식메서드(오버라이드 됨)");

   }

}

오버라이딩 된 상태에서 자식 객체로 해당 메서드를 호출하면 재 정의한 메서드가 호출되는 것입니다

Child child = new Child();

child.ParentMethod();//"자식메서드" 가 출력 됨

자바와는 달리 부모 클래스에서 virtual로 선언하지 않으면 오버라이딩을 할 수 없다는 것에 주의하세요

(자바는 모든 메서드가 기본적으로 virtual 이죠?)

참고로 virtual 이외에 abstract (추상 메서드) 로 정의되어 있는 메서드 역시 오버라이딩 가능합니다

오버라이딩의 핵심은 다형성(Polymorphism)

객체 지향의 중요한 개념 중에 하나가 바로 다형성 입니다

다형성은 같은 메시지에 다른 동작이 가능하게 하는 객체 지향의 특성인데요

이러한 다형적인 동작을 가능토록 구현하기 위해 오버라이딩 기법을 사용하게 됩니다

내용은 다르지만 같은 유ㄴ부모에서 태어난 자식클래스를 모두 사용하고자 할때 다형성을 기반으로 한 오버라이딩된 자식클래스이 모드 같은 메서드 이름이므로 한꺼번에 대량으로 처리가 가능한것입니다.

마치 스타에서 여러유닛을 한꺼번에 드래그하고 어택을 한방에 처리하는것처럼 말이지요

즉 모든 유닛에 한번의 Attack 명령으로 다형적인 동작이 가능토록 하는 것입니다. 코드를 보겠습니다

오버라이딩은 많은 객체 지향 디자인 패턴에 단골로 사용되는 기법입니다.


new

new 역시 오버라이딩처럼 상속과 연관이 있습니다.

new 를 통해 메서드를 재 정의하게 되면 부모 클래스의 원 메서드는 숨기게(가려지게)되는 차이가 있습니다.

말 그대로 메서드를 새로(new) 정의하는 기법입니다.

부모 클래스의 메서드를 사용하지 않고 새로 정의하는 것이죠. 코드를 보겠습니다

public class Parent{

   public void Parent(){

   Console.WriteLine("부모 메서드");

   }

}

public class Child : Parent{

   public new void Paren(){

   Console.WriteLine("자식메서드(새로 정의됨)");

   }

}

new 는 부모 메서드가 virtual 이거나 아니거나 상관이 없습니다


new
와 오버라이딩의 차이점

언뜻 보면 오버라이딩과 별반 달라 보이지 않지만. 엄연히 다릅니다.

오버라이딩과는 달리 new를 통한 메서드 재정의는 다형성과 아무런 연관이 없습니다

C#에서 상속 관계인 두 클래스에서 상위 타입으로의 형 변환은 묵시적으로 이루어 지기 때문에

다음과 같은 코드 작성이 가능합니다

Parent p = new Child();

p.Parent();

- 오버라이딩을 했을 경우 : 자식 클래스(Child)의 오버라이드 된 메서드가 실행됩니다.

- new 로 재정의 할 경우 : 부모 클래스(Parent)의 원 메서드가 실행됩니다

new 는 다형성과는 아무런 연관이 없습니다.

단순히 자식 클래스에서 새로이 정의한다는 것입니다

다시 말해 오버라이딩은 부모 타입으로 메서드를 호출하더라도 객체로 생성된 자식 타입의 메서드가 호출되도록 하여 객체의 다형성이 가능해 지는 것입니다.


'Development > C#' 카테고리의 다른 글

DependencyObject, DependencyProperty, PropertyMetadata  (0) 2012.03.15
WPF Resource  (0) 2012.03.15
CLR(Common Language Runtime)  (0) 2012.03.14
static, const, readonly, unsafe, fixed  (0) 2012.02.27
타입변환 (Boxing, UnBoxing)  (0) 2012.02.24