Computer >> 컴퓨터 >  >> 프로그래밍 >> C#

C# 동적 다형성(Dynamic Polymorphism) 개념과 예제로 쉽게 이해하기

다형성(Polymorphism)은 객체 지향 프로그래밍의 핵심 개념 중 하나로, 크게 정적 다형성(Static Polymorphism)동적 다형성(Dynamic Polymorphism)으로 구분할 수 있습니다.

정적 다형성 vs 동적 다형성

정적 다형성은 함수 호출에 대한 응답이 컴파일 시점(Compile Time)에 결정되는 방식입니다. 메서드 오버로딩(Method Overloading)과 연산자 오버로딩(Operator Overloading)이 대표적인 예입니다.

반면 동적 다형성은 함수 호출에 대한 응답이 런타임(Runtime)에 결정됩니다. 즉, 프로그램이 실행되는 도중에 실제 참조하는 객체의 타입에 따라 어떤 메서드가 호출될지 정해지는 것입니다. C#에서는 추상 클래스(Abstract Class)가상 함수(Virtual Function)를 통해 동적 다형성을 구현합니다.

동적 다형성 예제

다음 예제는 부모 클래스인 Shape와 이를 상속받는 Rectangle, Triangle 클래스를 통해 동적 다형성을 보여줍니다.

using System;

namespace PolymorphismApplication {
    class Shape {
        protected int width, height;

        public Shape(int a = 0, int b = 0) {
            width = a;
            height = b;
        }

        public virtual int area() {
            Console.WriteLine("Parent class area :");
            return 0;
        }
    }

    class Rectangle : Shape {
        public Rectangle(int a = 0, int b = 0) : base(a, b) {}

        public override int area() {
            Console.WriteLine("Rectangle class area :");
            return (width * height);
        }
    }

    class Triangle : Shape {
        public Triangle(int a = 0, int b = 0) : base(a, b) {}

        public override int area() {
            Console.WriteLine("Triangle class area :");
            return (width * height / 2);
        }
    }

    class Caller {
        public void CallArea(Shape sh) {
            int a;
            a = sh.area();
            Console.WriteLine("Area: {0}", a);
        }
    }

    class Tester {
        static void Main(string[] args) {
            Caller c = new Caller();
            Rectangle r = new Rectangle(10, 7);
            Triangle t = new Triangle(10, 5);

            c.CallArea(r);
            c.CallArea(t);
            Console.ReadKey();
        }
    }
}

코드 설명

  • Shape 클래스의 area() 메서드는 virtual 키워드로 선언되어 있어, 파생 클래스에서 재정의(Overriding)할 수 있습니다.
  • RectangleTriangle 클래스는 override 키워드를 사용하여 area() 메서드를 각자의 계산 방식에 맞게 재정의합니다.
  • Caller 클래스의 CallArea() 메서드는 매개변수로 Shape 타입을 받지만, 실제 실행되는 area()는 전달된 객체가 무엇인지에 따라 런타임에 결정됩니다.

실행 결과

Rectangle class area :
Area: 70
Triangle class area :
Area: 25

CallArea() 메서드에는 모두 Shape 타입으로 객체가 전달되었음에도 불구하고, 각 객체가 재정의한 area() 메서드가 호출되어 서로 다른 결과가 출력됩니다. 사각형은 너비 × 높이로 면적을 계산하고, 삼각형은 너비 × 높이 ÷ 2로 계산하는 것을 확인할 수 있습니다.

정리

이처럼 동적 다형성을 활용하면 호출부(Caller)의 코드를 수정하지 않고도 새로운 도형 클래스를 손쉽게 확장할 수 있습니다. 이는 코드의 유연성확장성을 크게 향상시켜 주며, 유지보수가 용이한 객체 지향 설계의 기반이 됩니다.