![[Java] 추상클래스와 인터페이스 차이점](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0w723%2FbtsMWvGjhQF%2F1KJya0VJxkTJrlLiQAtBN0%2Fimg.jpg)
원본글 출처 : 바로가기
☕ 인터페이스 vs 추상클래스 용도 차이점 - 완벽 이해
인터페이스 vs 추상클래스 비교 이 글을 찾아보는 독자분들은 아마도 이미 인터페이스와 추상클래스 개념을 학습한 뒤에 이 둘에 대하여 차이의 모호함 때문에 방문 했겠지만, 그래도 다시한번
inpa.tistory.com
추상 클래스
- 상속 받을 클래스들이 공통으로 가지는 메소드와 필드가 많아 중복 멤버 통합을 할때
- 멤버에 public 이외의 접근자(protected, private) 선언이 필요한 경우
- non-static, non-final 필드 선언이 필요한 경우 (각 인스턴스에서 상태 변경을 위한 메소드가 필요한 경우)
- 요구사항과 함께 구현 세부 정보의 일부 기능만 지정했을 때
- 하위 클래스가 오버라이드하여 재정의하는 기능들을 공유하기 위한 상속 개념을 사용할 때
- 추상 클래스는 이를 상속할 각 객체들의 공통점을 찾아 추상화시켜 놓은 것으로, 상속 관계를 타고 올라갔을 때 같은 부모 클래스를 상속하며 부모 클래스가 가진 기능들을 구현해야할 경우 사용한다.
중복되는 멤버를 통합 해주는 기능은 본래 추상 클래스의 기능이라기 보단 그냥 클래스의 기능이라고 하는게 옳다.
다만 같은 추상화 개념인 인터페이스와 차이점을 두기 위해, 상수 밖에 정의 못하는 인터페이스에서는 할 수 없는 기능이 추상 클래스 중복 멤버 통합이라고 보면 된다.
위의 다양한 종류의 Exam 시험 클래스에서 공통적으로 보는 국어, 영어, 수학 멤버 필드를 상속(extends)을 통해 상위 클래스로 묶고, 메서드도 통합하며 추상화(abstract)를 해주면서 나중에 다른 종류의 Exam 클래스를 추가/확장 하는데 있어 유연한 구조적인 객체 지향 설계를 만들수 있게 된다.
단순한 중복 멤버 제거를 떠나서, 클래스 끼리 명확한 계층 구조가 필요할때도 추상클래스를 사용한다.
공통된 기능 구현이 필요하거나, 공통으로 지켜야 할 규칙도 있을때 상속을 통해 구조화 하여 재정의(overriding)을 통해 구현한다.
인터페이스나 추상클래스나 다형성을 이용할수 있는데, 추상클래스를 통한 다형성을 이용할때에는, 부모 추상 클래스와 논리적으로 관련이 있는 확장된 자식 클래스들을 다룬다는 점에서, 클라이언트와 추상화 객체들은 의미적으로 관계로 묶여 있다라고 볼 수 있는 것이다.
인터페이스
- 어플리케이션의 기능을 정의해야 하지만 그 구현 방식이나 대상에 대해 추상화 할 때
- 서로 관련성이 없는 클래스들을 묶어 주고 싶을때 (형제 관계)
- 다중 상속(구현)을 통한 추상화 설계를 해야할때
- 특정 데이터 타입의 행동을 명시하고 싶은데, 어디서 그 행동이 구현되는지는 신경쓰지 않는 경우
- 클래스와 별도로 구현 객체가 같은 동작을 한다는 것을 보장하기 위해 사용
인터페이스의 가장 큰 특징은 상속에 구애 받지 않은 상속(구현) 가 가능하다는 것이다.
상속(extends)는 뭔가 클래스끼리 논리적인 타입 묶음의 의미가 있다면, 구현(implements)은 자유로운 타입 묶음의 의미이다. 그래서 서로 논리적이지 않고 관련이 적은 클래스끼리 필요에 의해 형제 타입 처럼 묶어 버릴 수 있다.
다음과 같이 Creature 라는 최상위 추상 클래스와 그 하위 추상 클래스인 Animal, Fish 가 있고, 각 추상 클래스를 구체적으로 의미 부여해 구현한 Parrot, Tiger, People 클래스와 Whale 클래스가 있다고 가정하자.
이렇게 상속 관계를 설정해 놓고 동작을 하는 메소드를 추가해야 하는데, 만일 수영 동작을 하는 swimming() 메소드를 각 자식 클래스에 추가해야 한다고 하자.
이때 나중에 확장을 위해 추상화 원칙을 따라야 한다고 한다. 그러면 부모나 조상 클래스에 추상 메소드를 추가해야 하는데, 수영은 고래(Whale) 과 사람(People)만 할수 있으니 이를 동시에 포함하는 Creature 추상 클래스에서 추상 메소드를 추가해야 한다. (호랑이와 앵무새는 수영을 못한다고 가정한다)
하지만 Creature 추상 클래스에 추상 메소드를 추가하면, 곧 이를 상속하는 모든 자손/자식 클래스에서 반드시 메소드를 구체화 해야한다는 규칙 때문에 실제로 수영을 못하는 호랑이(Tiger)와 앵무새(Parrot) 클래스에서도 메소드를 구현해야 하는 강제성이 생기게 된다.
물론 메소드를 선언하기만 하고 빈칸으로 놔두면 되기는 하지만, 이는 객체 지향 설계에 위반될 뿐만 아니라 나중에 유지보수 면에서도 마이너스 적인 효과가 된다.
따라서 상속에 얽매히지 않는 인터페이스에 추상 메소드를 선언하고 이를 구현(implements) 하면서 자유로운 타입 묶음을 통해 추상화를 이루게 하는 것이다.
이외에, 날아 다니는 동작 메서드나, 말하는 동작 메서드를 각각 인터페이스마다 분리하여 선언하고 이를 각 자식 클래스에 자유롭게 상속시킴으로써 보다 구조화된 객체 지향 설계를 추구 할 수 있는 것이다.
추상클래스는 클라이언트에서 자료형을 사용하기 전에 미리 논리적인 클래스 상속 구조를 만들어 놓고 사용이 결정되는 느낌이라면, 인터페이스는 반대로 먼저든 나중이든 그때 그때 필요에 따라 구현해서 자유롭게 붙였다 땟다하는 느낌으로 보면 된다.
'Language > Java' 카테고리의 다른 글
[Java] @NoArgsConstructor(access = AccessLevel.PROTECTED) (0) | 2025.04.01 |
---|---|
[Java] 정규 표현식 클래스 (0) | 2025.03.25 |
[Java] 형식(Format) 클래스 (0) | 2025.03.25 |
[Java] BigInteger 클래스 (0) | 2025.02.28 |
[Java] Optional<T> (1) | 2024.03.15 |