[C#] 인터페이스와 추상 클래스

Learning 

When: 1학년 5월 15일

 

How:

수업 시간에 인터페이스와 추상 클래스를 공부하고 정리하는 숙제가 있어서 이것도 하고 그것도 하기 위해 공부를 해보았습니다.

 

Understanding:

 

Interface:

먼저 인터페이스에 대해 설명을 해보겠습니다. 인터페이스는 약속이라고 많이 부르는데, 저는 처음 이 표현을 듣고 이해가 잘 안 되었기 때문에 조금 더 자세히 설명을 하자면, 잘되는 음식점 A가 있고 안 되는 음식점 B가 있습니다. 여기서 B의 사장이 직원이 필요해서 A의 사장에게 부탁을 했더니, 평소에 친하게 지내던 A의 사장이 수락을 하였습니다. 여기서 A의 직원은 실력을 보장받은 직원이기에 이것을 해라, 저것을 해라 이런 식으로 바로 명령을 할 수 있습니다. 실제로 하는 것은 보지 못했지만, 실력을 보장받았기에 맡은 일을 곧장 했습니다. 여기서 ‘보장받은 실력’이 인터페이스라고 생각하시면 되는데 (이해가 쏙쏙 안 되잖아요~) 인터페이스를 상속받은 클래스에는 무조건 인터페이스에 있는 메서드가 들어가야 합니다. 고로 인터페이스를 상속받은 클래스는 메서드 이름은 같지만 구현은 다른 그 클래스 고유의 메서드를 가지게 되는 것이고, 인터페이스 형식의 자식 클래스의 객체에서 메서드를 사용하면 그 객체의 메서드가 실행되어 같은 이름에 다른 구현을 가진 메서드를 많이 만들 수 있습니다. 그리고 그것을 하나의 형식에서 사용할 수 있다는 점이 인터페이스의 이점입니다. 이것을 보면 “그런데 이런 다형성을 이용하는 것은 그냥 클래스를 부모로 해도 되는 것 아니야?”라는 의문이 들 수 있는데, 정답입니다. 제가 방금 짠 코드는 일반 클래스를 오버라이드하는 것으로 구현이 충분히 가능합니다. 하지만 문제는 그 이후에 생깁니다. 만약 Enemy 클래스를 만들어서 파란 오크, 하얀 오크, 검은 오크... 고블린1, 고블린2, 고블린3...에게 모두 주었다고 해보겠습니다. 여기까지는 괜찮은데, 오크는 오크만을 위한 기능이 필요해질 수 있습니다. 여기서 그냥 Enemy 클래스에 기능을 추가한다면 고블린도 영향을 받을 것입니다. 클래스는 하나의 클래스만 상속받을 수 있기 때문입니다. 그럼 인터페이스는 어떨까요? 인터페이스는 얼마나 상속받든 상관없습니다. 여기서 오크 인터페이스를 만든 후, 오크들에게 상속만 시킨다면 클래스를 하나 더 상속시킨 것처럼 사용할 수 있는 것입니다. 인터페이스를 사용하는 예제를 써보겠습니다.

    public interface IEnemy //인터페이스를 사용할 때는 첫 글자에 I를 붙이는 것이 관례이다.
    {
        void Say();
    }
    public class WhiteOrc : IEnemy
    {
        public void Say()
        {
            Console.WriteLine("I'am orc");
        }
    }
    public class BlackOrc : IEnemy
    {
        public void Say()
        {
            Console.WriteLine("I'am orc");
        }
    }
    public class WhiteGoblin : IEnemy
    {
        public void Say()
        {
            Console.WriteLine("I'am goblin");
        }
    }
    public class BlackGoblin : IEnemy
    {
        public void Say()
        {
            Console.WriteLine("I'am goblin");
        }
    }

이런 식으로 사용을 한다면 나중에 IOrc 인터페이스를 추가하여 오크만의 메서드도 추가할 수 있습니다.

그런데 이런 식으로 사용을 하다 보면 오크의 종류가 많아졌을 때, 오크 메서드에 추가하고, 오크의 모든 클래스에 그 메서드를 구현하지 않으면 오류가 뜨고, 그렇게 하고 싶지도 않을 것입니다. 이럴 때 쓸 수 있는 것이 추상 클래스입니다.

추상 클래스:

추상 클래스는 인터페이스와 클래스의 사이(클래스에 더 가까움)라고 볼 수 있습니다. 그렇기에 클래스 + 무조건 구현해야 하는 메서드 만들기 기능이라고 봐도 되는데, 변수 선언, 메서드 선언과 구현까지 할 수 있고, 클래스처럼 두 개 이상 상속받을 수 없다는 점까지 클래스와 판박입니다. 차이점은 class 키워드를 사용하기 전에 abstract라는 키워드를 사용해야 하고, abstract로 수식된 메서드를 사용하면 interface에서 메서드를 만든 것과 같이 직접 구현할 수 없습니다. 인터페이스와 클래스는 별개이므로 interface와 함께 상속받을 수 있기 때문에 방금 같은 상황에서 모든 오크에 같은 메서드를 추가하고 싶을 때, 그 메서드가 구현된 abstract 클래스를 상속시키면 ‘Orc만 필요한 상속받은 클래스에서 구현해야 하는 메서드’도 추가할 수 있어서 좋습니다. 여기까지 보면 그냥 interface 대신 abstract 클래스를 사용하면 구현도 되고 구현 안 한 메서드도 추가할 수 있어서 좋은 것 같지만, interface는 여러 개를 추가할 수 있고 추상 클래스는 클래스처럼 필드를 만들거나 구현된 메서드를 만들 수 있어서 좋습니다.

 

Result: interface는 다중 상속이 필요할 때 사용하고, 추상 클래스는 구체적인 기능이 같을 때, 그 중에서 다른 기능이 조금 있을 때 사용하기 좋습니다.

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

[C#] 일반화 프로그래밍 (Generic 형식)  (0) 2025.06.07
[C#] Null값 받을 수 있는 변수, nullable 변수  (0) 2025.05.31
[C#] out, ref 키워드  (0) 2025.05.14
[C#] 프로퍼티  (0) 2025.05.13
[C#] 다형성  (0) 2025.05.12