객체 지향 인터페이스
📋 문서 버전
이 문서는 2개의 버전이 있습니다. 현재 버전 1을 보고 있습니다.
객체 지향 인터페이스
개요
객체향 인터페이스(Object-Oriented Interface)는 객체 지향 프로그래밍(Object-Oriented, OOP)에서 중요한 개념 중로, 클래스나 객체가 외부와 상호작용할 수 있도록 정의된 메서드의 집합을 의미. 인터페이스는 특정 기능을 어떻게 구현할지는 명시하지 않지만, 무엇을 제공해야 하는지를 규정함으로써 코드의 유연성, 재사용성, 유지보수성을 높이는 데 핵심적인 역할을 합니다.
인터페이스는 객체 지향 설계 원칙 중 하나인 의존성 역전 원칙(Dependency Inversion Principle)과 인터페이스 분리 원칙(Interface Segregation Principle)을 실현하는 데 필수적인 도구입니다. 특히 대규모 소프트웨어 개발에서 다양한 모듈이나 컴포넌트 간의 결합도를 낮추고, 테스트와 확장을 용이하게 만드는 데 기여합니다.
인터페이스의 정의와 목적
정의
인터페이스는 메서드 시그니처(이름, 매개변수, 반환 타입)만을 정의하고, 실제 구현은 포함하지 않는 추상적인 계약(contract)입니다. 즉, 인터페이스는 "이 클래스는 이런 행동을 해야 한다"는 요구사항을 명시합니다.
예를 들어, [Drawable](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4%EC%98%88%EC%A0%9C/Drawable)
이라는 인터페이스는 draw()
라는 메서드를 요구할 수 있으며, 이를 구현하는 모든 클래스는 draw()
메서드를 반드시 정의해야 합니다.
목적
인터페이스의 주요 목적은 다음과 같습니다:
- 추상화: 구현 세부 사항을 숨기고, 객체가 제공하는 기능에 초점을 맞춥니다.
- 다형성 지원: 서로 다른 클래스가 같은 인터페이스를 구현함으로써, 동일한 방식으로 처리될 수 있습니다.
- 결합도 감소: 클라이언트 코드가 구체 클래스가 아닌 인터페이스에 의존하게 되어, 변경에 강한 구조를 만듭니다.
- 역할 기반 설계: 객체가 수행하는 역할을 명확히 분리하여 설계의 명확성을 높입니다.
주요 프로그래밍 언어에서의 인터페이스
Java
Java는 인터페이스를 interface
키워드로 정의하며, 클래스는 implements
키워드를 사용해 인터페이스를 구현합니다.
interface Drawable {
void draw();
}
class Circle implements Drawable {
public void draw() {
System.out.println("원을 그립니다.");
}
}
Java 8 이후부터는 인터페이스에 default
메서드를 포함할 수 있어, 일부 구현을 제공하면서도 여전히 인터페이스의 본질을 유지합니다.
C
C#도 Java와 유사하게 interface
키워드를 사용하며, 다중 인터페이스 구현을 지원합니다.
public interface IDrawable
{
void Draw();
}
public class Rectangle : IDrawable
{
public void Draw()
{
Console.WriteLine("각형을 그립니다.");
}
}
C# 8.0부터는 인터페이스에 기본 구현(default implementation)과 정적 멤버도 허용됩니다.
Python
Python은 인터페이스를 언어 차원에서 엄격히 지원하지는 않지만, abc
모듈의 추상 기본 클래스(Abstract Base Class, ABC)를 통해 유사한 기능을 구현할 수 있습니다.
from abc import ABC, abstractmethod
class Drawable(ABC):
@abstractmethod
def draw(self):
pass
class Triangle(Drawable):
def draw(self):
print("삼각형을 그립니다.")
이 방식은 인터페이스의 계약을 강제하고, 구현 누락 시 오류를 발생시켜 설계의 일관성을 유지합니다.
인터페이스 설계의 모범 사례
1. 인터페이스 분리 원칙 준수
인터페이스는 너무 범용적이거나 많은 메서드를 포함하지 않아야 합니다. 작고 집중된 인터페이스를 설계하는 것이 바람직합니다.
interface Printer {
void print();
}
interface Scanner {
void scan();
}
이렇게 분리하면 PrintOnlyDevice
는 Printer
만 구현하고, MultiFunctionDevice
는 두 인터페이스를 모두 구현할 수 있습니다.
2. 의미 있는 이름 사용
인터페이스 이름은 역할이나 기능을 명확히 나타내야 하며, 보통 -able
, -ible
접미사를 사용합니다 (예: Runnable
, Serializable
).
3. 변경에 유연한 설계
인터페이스는 자주 변경되지 않도록 설계되어야 합니다. 자주 변경되는 기능은 추상 클래스나 다른 메커니즘을 고려하는 것이 좋습니다.
인터페이스와 추상 클래스의 차이
항목 | 인터페이스 | 추상 클래스 |
---|---|---|
메서드 구현 | 기본적으로 없음 (Java 8+부터 default 허용) | 일부 메서드에 구현 가능 |
상태(필드) | 상수만 가능 | 인스턴스 필드 가능 |
다중 상속 | 가능 (인터페이스는 다중 구현 지원) | 불가능 (Java 등 일부 언어) |
목적 | "할 수 있는 일" 정의 | 공통 구현과 상태 공유 |
참고 자료 및 관련 문서
- Oracle Java Documentation - Interfaces
- Microsoft Docs - C# Interfaces
- Python abc — Abstract Base Classes
- 객체 지향 설계 원칙 (SOLID)
- 디자인 패턴: Strategy, Observer, Factory 등
인터페이스는 소프트웨어 설계의 기초이자 핵심 도구로서, 체계적이고 확장 가능한 아키텍처를 구축하는 데 없어서는 안 될 요소입니다.
이 문서는 AI 모델(qwen-3-235b-a22b-instruct-2507)에 의해 생성된 콘텐츠입니다.
주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.