Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

nomad-programmer

[Programming/C#] 인터페이스 다중 상속 본문

Programming/C#

[Programming/C#] 인터페이스 다중 상속

scii 2020. 9. 11. 01:44

C#에서 클래스는 여러 클래스를 다중 상속할 수 없다. 이른바 "죽음의 다이아몬드" 라는 문제 때문이다.
죽음의 다이아몬드란, 조부모 클래스를 두 개의 파생 클래스가 상속하고, 이 두 개의 파생 클래스를 다시 하나의 자식 클래스가 상속하는 것을 말한다.

죽음의 다이아몬드 문제의 핵심은 "모호성" 이다.

컴파일은 MyVehicle이 어느 Ride() 메소드를 물려받도록 할까? Car의 Ride()? 아니면 Plane의 Ride()? 죽음의 다이아몬드 문제의 핵심은 모호성이다. 컴파일러 상태에 따라 Car의 Ride()가 물려받을 수도 혹은 Plane의 Ride()가 물려받을 수 있다.

클래스를 다중 상속하면 문제가 하나 더 발생한다. 바로 "업-캐스팅 (Up-Casting)" 문제이다. 다중 상속이 허용된다면 다음과 같은 코드가 가능할 것이다.

Plane plane = new MyVehicle();
Car   car   = new MyVehicle();

plane은 어떤 결과를 출력할까? "Run" 혹은 "Fly" 어떤것을 출력할까? 그것은 모를 일이고 알 수도 없다. 코드를 작성하는 프로그래머조차 확실할 수 없다. 이렇게 어떻게 동작할지 정확하게 예측할 수 없는 모호한 프로그램은 위험하다. 
다중 상속은 이런 위험성을 갖고 있다. 이런 위험은 소스 코드 수준에서 방지할 수 있는 것이 가장 좋다. 그래서 C#은 클래스의 다중 상속을 허용하지 않는다.

인터페이스는 내용이 아닌 외형을 물려준다. 즉, 정의는 없고 선언만 존재하는 것을 물려준다. 또한 속은 어떨지 몰라도 겉모습만큼은 정확하게 자신을 닮기를 강제한다. 따라서 죽음의 다이아몬드 같은 문제도 발생하지 않는다. 

프로그래머는 여러 인터페이스를 다중 상속하는 클래스를 안심하고 이용할 수 있다.
using System;

namespace CSharpExample
{
    interface IRunnable
    {
        void Run();
    }

    interface IFlyable
    {
        void Fly();
    }

    class FlyingCar : IRunnable, IFlyable
    {
        public void Run()
        {
            Console.WriteLine("Run!");
        }

        public void Fly()
        {
            Console.WriteLine("Fly!");
        }
    }

    class MainApp
    {
        static int Main(string[] args)
        {
            FlyingCar car = new FlyingCar();
            car.Run();
            car.Fly();

            IRunnable runnable = car as IRunnable;
            runnable.Run();

            IFlyable flyable = car as IFlyable;
            flyable.Fly();

            return 0;
        }
    }
}


/* 결과

Run!
Fly!
Run!
Fly!

*/
Comments