[Java] 합성 vs 인터페이스
자바 상속에 대해 구글링을 해보면 상속을 지양하고 합성을 지향하는 글을 많이 볼 수 있다.
초기에는 코드의 재사용(중복 방지), 유지보수의 편리함 등으로 많이 사용했던 것 같은데, 점점 다양한 기능을 요구하게 되고... 코드는 복잡해지고...
오히려 부모 클래스까지 찾고, 파악하고, 수정하는 일이 더 비효율적인 방식이 되어버린 것 같다.
그리고 여기에 점점 발전하는 PC의 성능으로 과거에 비해 메모리 사용에 대한 걱정이 덜하기 때문이 아닐까 싶다.
자바에서 합성(composition)과 인터페이스(interface)는 객체 간 관계를 설계할 때 사용하는 개념으로, 둘 다 다형성을 목적으로 쓰지만, 어떨 때 어떤 걸 써야 할지 구분하는 게 중요하다.
1. 합성이란?
필드에 다른 클래스의 인스턴스를 참조하게 만드는 설계.
서로 관련없는 클래스 관계에서 다른 클래스의 기능을 사용해야 한다면? 합성 방식을 사용한다고 보면 된다.
- 합성은 왜 사용할까?
- 상속보다 유연하다. (부모 클래스가 바뀌어도 영향을 덜 받음)
- 재사용이 용이하다. (객체만 변경하면 됨)
- 캡슐화 (참조한 객체는 외부에서 직접 접근이 불가)
- 코드 예시
// 별도의 기능 클래스
class Engine {
public void start() {
System.out.println("Engine started.");
}
}
// 자동차는 엔진을 '가지고 있음'
class Car {
private Engine engine;
public Car() {
engine = new Engine(); // 합성
}
public void startCar() {
engine.start();
System.out.println("Car is moving.");
}
}
public class CompositionTest {
public static void main(String[] args) {
Car car = new Car();
car.startCar();
// 출력
// Engine started.
// Car is moving.
}
}
위의 예시처럼 각각의 기능 (엔진, 페달, 핸들, 브레이크 등)을 가진 클래스를 참조해 자동차를 완성하는 걸 합성이라고 보면 이해가 조금 더 쉬울 듯 하다.
확실히 상속에 비해 의존성이 낮고, 에러가 발생해도 유지보수 측면에서 훨씬 유리하다고 생각한다.
인터페이스 또한 합성처럼 여러 기능을 받아 (implements) 사용할 수 있는데, 자식 클래스에서 반드시 기능을 구현해야한다는 점이 어느정도 의존도를 부여한다.
2. 인터페이스란?
동작을 자식 클래스가 반드시 구현해 사용하도록 하는 것.
인터페이스는 무엇을 할 수 있는지만 정의하고 어떻게 하는지는 자식 클래스에서 정한다.
- 인터페이스는 왜 사용할까?
클래스에게 다중상속이 필요할 때 사용한다. (반드시 오버라이딩해서 사용해야 함)
수행하는 동작은 유사하나 다양한 성격의 클래스가 필요할 경우, 인터페이스를 통해 각 클래스가 인터페이스의 추상 메서드를 구현하여 클래스들을 하나의 자료형으로 묶어준다.
- 코드 예시
// 인터페이스: 날 수 있는 능력
interface Flyable {
void fly();
}
// 클래스가 날 수 있도록 기능 부여
class Bird implements Flyable {
@Override
public void fly() {
System.out.println("Bird is flying.");
}
}
class Airplane implements Flyable {
@Override
public void fly() {
System.out.println("Airplane is flying.");
}
}
public class InterfaceTest {
public static void main(String[] args) {
Flyable f1 = new Bird();
Flyable f2 = new Airplane();
f1.fly(); // Bird is flying.
f2.fly(); // Airplane is flying.
}
}
3. 합성 vs 인터페이스
| 예시 | 추천 |
|---|---|
| 객체가 다양한 부품을 조립해서 기능을 사용하게 하고 싶다 | 합성 |
| 상속 대신 더 유연한 구조가 필요할 때 | 합성 |
| 동일한 기능을 여러 클래스에 부여하고 싶다 | 인터페이스 |
| 행위(기능)의 통일성을 강조하고 싶을 때 | 인터페이스 |
참고
Leave a comment