상속 vs 인터페이스

60jong·2023년 7월 14일
0

Java

목록 보기
12/14
post-thumbnail

이번 글을 통해

  • 상속과 인터페이스의 목적
  • 상속과 인터페이스의 장단점
  • 상속과 인터페이스에 대한 평가
  • 결론

에 대해 정리하고자 한다.

상속과 인터페이스의 목적

상속

상속은 같은 부류의 클래스임을 활용해 코드의 재사용이 가장 큰 목적이라고 생각한다.

인터페이스

인터페이스는 구현에서 관심을 분리하는 것이 가장 큰 목적이다. 좀 더 구체적으로 합성(Composition)을 통해 의존/결합도를 낮추는 것이 목적이라고 생각한다.

상속과 인터페이스의 장단점

상속

장점

상속의 장점은 상속의 목적처럼 코드의 재사용이다.

예시를 통해 보자면

class Animal {
	public void breathe();
}
class Dog extends Animal {
	public void breathe(); -- 부모의 메서드 구현을 사용 가능
}

Dog is a Animal 이라는 관계가 성립하기에 Dog 클래스는 Animal 클래스를 상속하는 것에 문제가 없다. Dog 클래스는 Animal 클래스를 상속함으로써 breathe()라는 기능을 구현 없이 사용할 수 있다는 것이 장점이다. - 재사용

단점

상속의 장점인 코드 재사용은 결국 부모에 대한 자식의 의존도, 결합도를 높인다. 그 이유는 Dog 클래스가 breathe() 기능을 사용하기 위해서는 Animal 클래스를 들여다보아서 해당 기능을 잘 이해해야 한다. 더 나아가 많은 기능, 여러 계층의 상속 (A extends B extends C extends D)이 있는 경우에 어느 breath()가 어느 클래스에 있는 기능인지 확인하기 어려울 것이다.

그리고 부모 클래스에 변화가 필요할 때에는 모든 자식 클래스를 고려해야한다... 부모의 바뀐 기능이 자식에게 어떤 악영향을 끼칠지 모르기 때문이다.

인터페이스

장점

인터페이스 또한 목적에 그 장점이 나타나있다. 구현에 대한 관심을 분리함으로써 결합도, 의존도를 낮출 수 있다.

예시를 통해 보자면

interface Animal {
	void breathe();
}
// Animal을 구현한 Dog
class Dog implements Animal {
	@Override
	public void breathe() {
    	System.out.println("Breathe Like Dog.");
    }
}
--------------------------------------------------------
class Main {
	
    Animal animal;
    
	public Main(Animal animal) {
    	this.animal = animal;
    }
    
    public void doSomething() {
    	animal.breathe();
    }
}

Main 클래스를 보면 진짜 아름답다... 오로지 Animal이라는 인터페이스 (역할)에만 의존하고 있을 뿐, 그 구현에는 관심도 없고, 제약도 받지 않는다. 내가 원할 때 런타임에서 Animal에 대한 구현체로 Dog / Cat / Tiger 등으로 바꿔주어도 Main 클래스에 대해선 수정할 것이 하나도 없다.

이외에도 정말 많은 장점이 있을 것이다. 하지만 강조하고 싶은 것은 구현에 관심이 없다라는 점이다. 이로 인해 Main 클래스와 Animal 인터페이스에 대한 의존도, 결합도는 낮아지게 된다.

단점

이렇게 좋은 인터페이스에도 단점이 있기 마련이다. 인터페이스는 항상 구현을 해서 구현 클래스를 만들어야하는데, 많은 중복 코드가 발생할 수도 있다. -- 이는 상속의 코드 재사용과 대립되겠다.

상속과 인터페이스에 대한 평가

상속과 인터페이스에 대해서는, 특히 상속에 관해서는 말이 참 많다.

Java의 창시자인 제임스 고슬링(James Arthur Gosling)이 한 인터뷰에서 
"내가 자바를 만들면서 가장 후회하는 일은 상속을 만든 점이다" 라고 말할 정도 이다.
조슈야 블로크의 Effective Java에서는 상속을 위한 설계와 문서를 갖추거나, 
그럴 수 없다면 상속을 금지하라는 조언을 한다.

따라서 추상화가 필요하면 인터페이스로 implements 하거나 
객체 지향 설계를 할땐 합성(composition)을 이용하는 것이 추세이다.

이러한 말도 있을 정도니까. 상속은 코드 재사용을 위한 절자지향 방법이다.라는 관점도 보았다.

결론

내가 인터페이스에 대해 극찬을 한 이유와 상속의 단점을 소개할 때 기준은 단 하나였다.

구현에 대한 관심 분리 -> 의존도 낮춤

요즘 개발 트렌드는 재사용 < 유연함인 것 같다. 인터페이스의 단점으로 소개할 때 항상 구현에 있어 중복이 발생할 수 있다는 점에서 "재사용을 위해 상속을 고려"할 필요가 이젠 없다고 생각이 들었다.

물론 클래스간 확실한 is a 관계가 있고

profile
울릉도에 별장 짓고 싶다

0개의 댓글