소년포비의 세계정복!!

오버로딩,오버라이딩 그리고 new 본문

프로그램 세상/C#

오버로딩,오버라이딩 그리고 new

소년포비 2009. 10. 6. 06:31

 

C# 언어적인 특징의 기본적인 사항이지만,

의외로 간과하거나 초보 개발자 분들이 헷갈려 하는 Overloading(오버로딩),Overriding(오버라이딩)

에 대해서 알아보기로 하자.

Overloading딩의 경우 메서드 및 연산자에 대한 오버로딩이 있으나 여기서는 메서드 오버로딩만 알아보기로 한다.

또한 Overriding 과 연계해 메서드에 적용하는 new  연산자도 같이 알아보자.

 

 

1. 오버로딩 (Overloading)

 

일반적으로 하나의 Class 에 동일한 이름의 메서드가 중복정의 될 수 없다.

만일 아래와 같이 중복되는 메서드를 생성했다면 반드시 컴파일 오류를 일으킬 것이다.

 

public class MyClass{

        public int MyMethod(){

            return 0;

        }

        public int MyMethod(){

            return 0;

        }

}

 

 

 

 

그러나 C# 오버로딩 기법을 사용하면 동일한 이름의 메서드를 여러 개 사용할 수 있다.

C# 컴파일러는 동일한 이름을 가진 두개 이상의 메서드가 있을 경우 이 메서드들의 파라메타들의

정보를 기준으로 메서드를 식별한다.

 

* 메서드 시그너처 (Signature)

메서드 시그너처란 메서드 이름, 파라메타 정보(타입,개수)를 말한다.

public int MyMethod(int n,string s)

메서드 시그너처는 클래스 내에서 유일해야 한다

 

정확히 말해서 C# 컴파일러는 메서드의 시그너쳐(Signature) 로 각 메서드를 구분한다.

결국 메서드 오버로딩은 한 클래스내에서 이름이 같아도 파라메타 정보(타입,개수) 가 다르면 서로 다른 시그너처이므로 가능하게 되는 것이다.

 

위의 예에서 다음과 같이 시그너처를 바꿔주면 오류없이 실행 가능하게 된다.

 

public int MyMethod(){

      return 0;

 }

 public int MyMethod(int n){

      return 0;

 }

 

결국 메서드 오버로딩에서의 각 메서드는 C# 컴파일러 입장에서 보면 각기 다른 메서드로 식별되지만

이를 사용하는 입장에서는 동일한 이름으로 접근할 수 있도록 함으로써 사용상의 편의성을 제공해 준다고 볼 수 있다.

 

 

2. 오버라이딩(Overriding)

 

메서드 오버로딩(Overloading) 은 동일한 클래스 내에 같은 이름의 메서드를 사용할 수 있도록 하는 특징인 반면,

메서드 오버라이딩은 클래스의 상속과 연관이 있다.

 

일반적으로 공용(public) 메서드는 자식에게 그대로 상속된다.

다음의 클래스를 보자.

 

public class ParentClass

{

    public int MyMethod()

    {

        return 0;

    }               

}

public class ChildClass : ParentClass

{

}

 

ChildClass MyMethod 메서드를 정의하지는 않았지만 부모 클래스(ParentClass)로부터

상속 받았기 때문에 MyMethod 를 사용할 수 있게 된다.

즉 다음과 같은 프로그래밍이 가능하게 된다

 

ChildClass c = new ChildClass();

c.MyMethod();

 

이렇듯 상속을 사용하면 기존의 코드를 재사용 할 수 있는 장점이 있다.

 

그러나 경우에 따라서는 부모클래스의 메서드를 자식 클래스에서 다르게 구현해야 할 때도 있다.

메서드 오버라이딩(Overriding) 은 이렇게 부모로부터 상속되어진 메서드를 재정의 할 때 사용하는 기법이다.

즉 부모클래스 에서 구현된 메서드를 그대로 상속받지 않고 자식 클래스에서 새로 재정의 해서 다른 일을 하도록 구현하는 것이다.

 

public class ParentClass

{

    public virtual int MyMethod()

    {

        return 0;

    }               

}

public class ChildClass : ParentClass

{

    public override int MyMethod()

    {

        return 1;

    }

}

 

부모 클래스에서는 자식클래스에서 재정의 할 수 있도록 virtual(가상) 메서드로 정의하고,

자식클래스에서는 이렇게 정의된 가상 메서드를 override(재정의) 하면 된다.

(재정의 하기 위해서는 부모 클래스의 메서드가 virtual 이거나 abstract 이어야 한다)

재정의 해서 자식클래스로 객체를 생성하면 재정의된 메서드가 호출되는 것이다.

ParentClass c = new ChildClass();

Console.WriteLine(c.MyMethod()); // 1 이 출력된다.

 

이런 메서드 재정의 기법은 객체지향의 다형성을 가능하게 한다.

동일한 타입의 객체로 서로 다른 일을 할 수 있도록 하는 다형성은 아주 유용한 개념이다.

 

다형성의 유용함을 보다 자세히 알고 싶으면 객체지향 관련 서적이나 디자인패턴 관련

서적을 살펴보기를 강력히 권장하는 바이다

다음 글은 다형성을 주제로 하지는 않지만 다형적인 동작에 대한 힌트를 얻을 수 있다.

Generics 제약 조건

 

 

 

3. NEW

 

메서드에 사용되는 new 연산자도 오버라이딩(Overriding) 처럼 클래스의 상속과 관련이 있다.

이는 부모 클래스에 정의된 메서드를 숨기는 역할을 한다고 볼 수 있다.

다음의 코드를 보자.

 

public class ParentClass

{

    public int MyMethod()

    {

        return 0;

    }               

}

public class ChildClass : ParentClass

{

    public new int MyMethod()

    {

        return 1;

    }

}

 

new 를 통해서 부모 클래스의 메서드를 새로 정의할 때는 부모 메서드가 virtual (가상) 이거나 아니거나 상관이 없다.

위의 구현은 MyMethod 라는 메서드를 자식클래스에서 그대로 상속받도록 하지 않고 새로이 정의해서 사용한다라고 해석 될 수 있겠다.

ChildClass c = new ChildClass();

Console.WriteLine(c.MyMethod()); // 1 을 출력한다

 

 

 

* 오버라이딩과 new 의 차이점

 

그런데 언뜻 봐서는 메서드 오버라이딩(Overriding) new 메서드는 별반 달라 보이지 않는다.

그러나 이 둘은 아주 큰 차이점이 있다.

그것은 바로 앞서 언급한 객체지향의 다형성과 관련된 내용이다.

방금 전 new 로 새로 선언한 메서드를 다음과 같이 사용했다.

ChildClass c = new ChildClass();

Console.WriteLine(c.MyMethod()); // 1 을 출력한다

 

그러나 다음과 같이 부모 타입으로 클래스 멤버에 접근 할 경우,

ParentClass c = new ChildClass();

Console.WriteLine(c.MyMethod());

결과는 0을 반환한다.

 

즉 객체를 생성할 때 자식타입으로 생성했지만 (new ChildClass()) 이를 부모 타입으로 접근하게 되면 여전히 부모클래스에 정의된 메서드가 호출 되는 것이다.

 

오버라이딩(Overriding) 의 경우 다르게 동작한다.

ParentClass c = new ChildClass();

Console.WriteLine(c.MyMethod());

결과는 1을 반환한다.

 

다시 말하지만, 오버라이딩은 부모 타입으로 메서드에 접근하더라도 인스턴스가 생성된

자식타입의 메서드가 호출되도록 하여 객체의 다형적인 동작이 가능토록 하는 것이다.

'프로그램 세상 > C#' 카테고리의 다른 글

C# 미니팝업창 애니메이션 효과  (0) 2009.10.07
문자열 다루기  (0) 2009.10.06
[ExecuteUnit] Process & Thread 개요  (0) 2009.10.06
[ExecuteUnit] Process 다루기 Demo  (0) 2009.10.06
[Thread][동기화] Event  (0) 2009.10.06