본문 바로가기
Programming/C#

C# 다형성 (Polymorphism) 객체지향 프로그래밍의 유연성과 확장성

by Dev_카페인 2024. 6. 9.
반응형

[C#] 다형성 (Polymorphism)  : 객체지향 프로그래밍의 유연성과 확장성

안녕하세요! 이번 포스트에서는 C#의 다형성(Polymorphism)에 대해 자세히 알아보겠습니다. 다형성은 객체지향 프로그래밍의 핵심 개념 중 하나로, 코드의 유연성과 확장성을 크게 향상시킵니다.

다형성이란 무엇인가요?

다형성은 "하나의 인터페이스로 여러 형태를 구현할 수 있는 능력"을 의미합니다. 이를 통해 동일한 메서드 호출이 객체의 타입에 따라 다른 동작을 수행할 수 있습니다. 다형성은 주로 상속과 인터페이스를 통해 구현됩니다.

다형성의 종류

  1. 컴파일 타임 다형성 (Compile-Time Polymorphism): 메서드 오버로딩과 연산자 오버로딩을 통해 구현됩니다.
  2. 런타임 다형성 (Run-Time Polymorphism): 메서드 오버라이딩을 통해 구현됩니다.

컴파일 타임 다형성

메서드 오버로딩 (Method Overloading)

메서드 오버로딩은 같은 이름의 메서드를 여러 개 정의하되, 각 메서드가 서로 다른 매개변수를 갖는 방식입니다.

public class MathOperations
{
    public int Add(int a, int b)
    {
        return a + b;
    }

    public double Add(double a, double b)
    {
        return a + b;
    }
}

위 예시에서 Add 메서드는 정수와 실수를 더할 수 있는 두 가지 버전이 있습니다. 호출되는 메서드는 전달되는 인수의 타입에 따라 결정됩니다.

연산자 오버로딩 (Operator Overloading)

연산자 오버로딩은 사용자 정의 타입에 대해 연산자를 정의할 수 있는 기능입니다.

public class Complex
{
    public int Real { get; set; }
    public int Imaginary { get; set; }

    public Complex(int real, int imaginary)
    {
        Real = real;
        Imaginary = imaginary;
    }

    public static Complex operator +(Complex c1, Complex c2)
    {
        return new Complex(c1.Real + c2.Real, c1.Imaginary + c2.Imaginary);
    }
}

위 예시에서 + 연산자는 Complex 객체를 더할 수 있도록 오버로딩되었습니다.

런타임 다형성

런타임 다형성은 주로 상속과 인터페이스를 통해 구현되며, 메서드 오버라이딩을 사용합니다. 이를 통해 부모 클래스의 참조 변수가 자식 클래스의 객체를 참조할 때, 실제 객체의 타입에 따라 적절한 메서드가 호출됩니다.

메서드 오버라이딩 (Method Overriding)

public class Animal
{
    public virtual void Speak()
    {
        Console.WriteLine("Animal sound");
    }
}

public class Dog : Animal
{
    public override void Speak()
    {
        Console.WriteLine("Bark");
    }
}

public class Cat : Animal
{
    public override void Speak()
    {
        Console.WriteLine("Meow");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Animal myDog = new Dog();
        Animal myCat = new Cat();

        myDog.Speak(); // Bark
        myCat.Speak(); // Meow
    }
}

위 예시에서 Animal 클래스의 Speak 메서드는 자식 클래스인 Dog와 Cat에서 오버라이딩되었습니다. Animal 타입의 변수가 실제로 어떤 객체를 참조하느냐에 따라 Speak 메서드의 호출 결과가 달라집니다.

인터페이스를 통한 다형성

인터페이스는 클래스가 구현해야 하는 메서드와 속성의 집합을 정의합니다. 인터페이스를 통해 다형성을 구현하면, 서로 다른 클래스가 동일한 인터페이스를 구현하여 일관된 방식으로 동작할 수 있습니다.

public interface IFlyable
{
    void Fly();
}

public class Bird : IFlyable
{
    public void Fly()
    {
        Console.WriteLine("Bird is flying");
    }
}

public class Airplane : IFlyable
{
    public void Fly()
    {
        Console.WriteLine("Airplane is flying");
    }
}

class Program
{
    static void Main(string[] args)
    {
        IFlyable[] flyingObjects = { new Bird(), new Airplane() };

        foreach (var obj in flyingObjects)
        {
            obj.Fly();
        }
    }
}

위 예시에서 Bird와 Airplane 클래스는 IFlyable 인터페이스를 구현합니다. IFlyable 타입의 배열을 통해 두 객체의 Fly 메서드를 호출하면, 각 객체의 실제 타입에 따라 적절한 메서드가 실행됩니다.

다형성의 이점

  1. 유연성: 동일한 인터페이스를 통해 다양한 객체를 처리할 수 있습니다.
  2. 확장성: 새로운 클래스가 기존 클래스를 변경하지 않고도 기능을 확장할 수 있습니다.
  3. 유지보수성: 코드를 재사용하고, 변경 사항을 최소화하여 유지보수가 용이합니다.

다형성과 디자인 패턴

다형성은 여러 디자인 패턴의 핵심 요소로 사용됩니다. 대표적으로 전략 패턴, 상태 패턴, 추상 팩토리 패턴 등이 다형성을 활용합니다.

마치며

이번 포스트에서는 C#의 다형성에 대해 알아보았습니다. 다형성은 객체지향 프로그래밍의 강력한 기능으로, 코드의 유연성과 확장성을 크게 향상시킵니다. 이를 통해 더 나은 구조의 프로그램을 작성할 수 있습니다. 추가적인 질문이나 궁금한 점이 있다면 언제든지 댓글로 남겨주세요!

반응형