C#은 Java와 마찬가지로 대표적인 객체 지향 프로그래밍(OOP) 언어로, 캡슐화(Encapsulation), 추상화(Abstraction), 상속(Inheritance), 다형성(Polymorphism)이라는 객체 지향의 핵심 개념을 완벽하게 지원합니다.
그중에서도 '추상화'를 구현하는 대표적인 방법이 바로 추상 클래스(Abstract Class)와 인터페이스(Interface)입니다. 두 기능 모두 C# 프로그램에서 추상화를 제공하지만, 사용 목적과 동작 방식에는 뚜렷한 차이가 있습니다.
추상 클래스와 인터페이스의 기본 개념
추상 클래스(Abstract Class)
추상 클래스는 직접 인스턴스(객체)를 생성할 수 없는 클래스로, 파생 클래스(자식 클래스)가 반드시 구현해야 하는 기능을 미리 정의해 둘 수 있습니다. 즉, 공통된 기능을 부모 클래스에서 구현하고, 세부 동작은 자식 클래스에서 완성하도록 강제하는 역할을 합니다.
인터페이스(Interface)
인터페이스는 메서드의 시그니처(이름, 매개변수, 반환 타입)만 정의할 수 있으며, 실제 구현 내용은 포함할 수 없습니다. 이 인터페이스를 상속받는 클래스가 해당 함수들을 직접 구현해야 하며, 일종의 '클래스가 가져야 할 행동 규약'이라고 볼 수 있습니다.
추상 클래스와 인터페이스의 핵심 차이점
아래 표는 두 개념의 가장 중요한 차이점을 항목별로 정리한 것입니다.
| 번호 | 구분 | 추상 클래스 | 인터페이스 |
|---|---|---|---|
| 1 | 정의 | 개념적으로 인스턴스화할 수 없는 클래스이며, 하나 이상의 순수 가상(추상) 함수를 포함하는 클래스로 구현됩니다. | 이 인터페이스를 상속하는 클래스가 반드시 구현해야 하는 멤버 함수들의 명세입니다. 즉, 클래스의 동작(행위)을 설명합니다. |
| 2 | 구현 | C#의 일반 클래스처럼 선언과 함께 자체적인 구현 코드를 가질 수 있습니다. | 메서드의 시그니처만 가질 수 있으며, 실제 구현은 해당 인터페이스를 상속받는 클래스가 제공합니다. |
| 3 | 상속 | C#에서는 하나의 클래스가 다른 클래스를 하나만 상속할 수 있으므로, 다중 상속이 불가능합니다. | 하나의 클래스가 여러 개의 인터페이스를 동시에 구현할 수 있으므로, 사실상 다중 상속의 효과를 얻을 수 있습니다. |
| 4 | 생성자 | 다른 클래스와 마찬가지로 생성자를 가질 수 있으며, 이를 통해 추상 클래스의 비정적(non-static) 메서드에 접근할 수 있습니다. | 생성자가 없기 때문에 직접 인스턴스화할 수 없으며, 인터페이스의 메서드는 이를 구현하는 클래스의 인스턴스를 통해서만 접근 가능합니다. |
| 5 | 접근 한정자 | 일반 클래스와 유사하게 public, private, protected 등 다양한 접근 한정자를 사용할 수 있습니다. | 외부 클래스에서 구현되어야 하므로 public 접근 한정자만 허용됩니다. |
| 6 | 성능 | 메서드와 그 구현을 함께 가지고 있어 성능이 상대적으로 더 빠릅니다. | 호출 시 해당 클래스에서 실제 메서드를 찾는 과정이 필요하기 때문에 성능이 상대적으로 느립니다. |
언제 무엇을 사용해야 할까?
추상 클래스는 관련 있는 클래스들 간에 공통 기능과 상태를 공유하고, 일부 기능만 자식 클래스에게 위임하고 싶을 때 적합합니다. 반면 인터페이스는 서로 관련 없는 클래스들에게 특정 기능(계약)을 강제하거나, 다중 상속이 필요한 경우에 활용하는 것이 좋습니다.
두 개념의 차이를 정확히 이해하면 더 유연하고 확장 가능한 C# 프로그램을 설계할 수 있습니다.