Search

이것이 C#이다: 8장 - 인터페이스와 추상 클래스

1. 인터페이스: 약속의 청사진

인터페이스는 C#에서 클래스가 따라야 할 '약속'을 정의합니다. 이는 마치 건축 설계도와 같아서, 어떤 기능(메소드)이 있어야 하는지는 명시하지만 그 내부 구현은 클래스에 맡깁니다.

1.1 인터페이스의 특징

인터페이스는 다음과 같은 독특한 특징을 가집니다:
메소드, 이벤트, 인덱서, 프로퍼티만 포함 가능
구현부 없이 선언만 가능
모든 멤버는 암시적으로 public
인스턴스 생성 불가
예를 들어, 다음과 같이 간단한 인터페이스를 선언할 수 있습니다:
public interface ILogger { void LogMessage(string message); bool IsEnabled { get; set; } }
C#
복사
이 인터페이스를 구현하는 클래스는 반드시 LogMessage 메소드와 IsEnabled 프로퍼티를 제공해야 합니다.

1.2 인터페이스 상속과 다중 상속

C#에서는 클래스의 다중 상속을 허용하지 않지만, 인터페이스의 다중 상속은 가능합니다. 이는 "죽음의 다이아몬드" 문제를 예방하면서도 유연한 설계를 가능케 합니다.
public interface IAdvancedLogger : ILogger { void LogError(Exception ex); } public class FileLogger : IAdvancedLogger, IDisposable { // ILogger 구현 public void LogMessage(string message) { /* ... */ } public bool IsEnabled { get; set; } // IAdvancedLogger 구현 public void LogError(Exception ex) { /* ... */ } // IDisposable 구현 public void Dispose() { /* ... */ } }
C#
복사
이 예제에서 FileLogger 클래스는 IAdvancedLoggerIDisposable 두 인터페이스를 동시에 구현합니다.

1.3 인터페이스의 기본 구현 메소드

C# 8.0부터는 인터페이스에 기본 구현 메소드를 추가할 수 있게 되었습니다. 이는 기존 인터페이스에 새 기능을 추가할 때 매우 유용합니다.
public interface ILogger { void LogMessage(string message); bool IsEnabled { get; set; } // 기본 구현 메소드 void LogWarning(string warning) { LogMessage($"WARNING: {warning}"); } }
C#
복사
이제 ILogger를 구현하는 클래스들은 LogWarning 메소드를 반드시 구현할 필요가 없으며, 필요한 경우에만 오버라이드할 수 있습니다.

2. 추상 클래스: 인터페이스와 클래스의 중간 지점

추상 클래스는 인터페이스와 일반 클래스의 특성을 모두 가지고 있습니다. 인터페이스처럼 구현을 강제할 수 있으면서도, 클래스처럼 일부 구현을 제공할 수 있습니다.

2.1 추상 클래스의 특징

인스턴스 생성 불가
구현된 멤버와 추상 멤버 모두 포함 가능
접근 제한자 사용 가능
생성자, 필드 등 클래스의 모든 멤버 포함 가능
public abstract class LoggerBase { protected bool isEnabled; public abstract void LogMessage(string message); public virtual bool IsEnabled { get { return isEnabled; } set { isEnabled = value; } } public void LogInfo(string info) { if (IsEnabled) LogMessage($"INFO: {info}"); } }
C#
복사
이 추상 클래스는 LogMessage를 추상 메소드로 선언하여 파생 클래스에서의 구현을 강제하면서도, LogInfo와 같은 공통 기능을 제공합니다.

결론

인터페이스와 추상 클래스는 각각 고유의 특성과 사용 시나리오를 가지고 있습니다. 인터페이스는 다중 구현이 가능하고 계약의 성격이 강한 반면, 추상 클래스는 일부 구현을 포함할 수 있어 관련 클래스들의 공통 기능을 정의하는 데 유용합니다.
개인적으로 이 개념들을 학습하면서 초기에는 언제 인터페이스를 사용하고 언제 추상 클래스를 사용해야 할지 혼란스러웠습니다. 하지만 실제 프로젝트에 적용해보면서 그 차이와 활용법을 체득할 수 있었습니다.
인터페이스와 추상 클래스는 디자인 패턴의 필수적인 요소입니다. 앞으로 디자인 패턴에 대해 학습하며 어떻게 활용되는지 깊이 있게 살펴볼 수 있을 것 같습니다.

참고 자료

박상현, "이것이 C#이다", 한빛미디어, 2023