위 세가지 개념의 정의와 차이, 각각 잘 쓰이는 경우 등에 대해 정리해보고자 한다.
extends
클래스 B기능을 확장
시킬 수 있다implements
인터페이스 B추상 메서드
는 구현체에서 구현(로직)되어야 한다강제성 부여
클래스
- 로직(기능) 정의 O (추상 메서드 제외)
- 다중 상속 불가능 / 다중 구현 가능
인터페이스
- 로직(기능) 정의 X (모두 추상 메서드)
- 다중 상속 가능
Abstraction
- 선언부(What)는 보여주지만, 내부 구현부(How)는 숨기는 형태
- 추상 메서드, 인터페이스는 추상화를 위해 사용된다.
추상 메서드
가 하나 이상 OR abstract
로 정의된 클래스.
생성자를 가지기 때문에 객체화
가 가능하다.
super()
을 통해 초기화가 가능하다.예시
public abstract class AbstractClass {
// Field
private String name;
private String id;
// Constructor
public AbstractClass(String name, String id){
this.name = name;
this.id = id;
}
// Abstract Method
public method() { }
}
public class RealClass extends AbstractClass {
private String number;
public RealClass(String name, String id, String number) {
// 초기화
super(name, id);
this.number = number;
}
}
추상 메서드
인 형태.추상 메서드 + 상수의 집합
default method
를 지원하여 기존 인터페이스 기능을 확장할 수 있다. (그럼 추상 클래스 대신 인터페이스만 사용하면 되지 않을깡..?)객체화
가 불가능하다.위 설명을 보면 추상 클래스와 인터페이스의 용도가 비슷하게 느껴진다.
그냥 둘 중 하나만 선택해 사용하면 될 것 같지만.. 한번 둘의 목적을 구분해보자.
Abstract Class
의 목적
- 상속을 받아 기능을 확장시키는 것
Interface
의 목적
- 구현체에게 특정 메서드가 반드시 존재하도록 강제
음.. 잘 와닿지가 않는다.
고민을 많이 하던 중, 괜찮은 포스트를 발견해 예시를 보고 추상 클래스와 인터페이스가 각자 존재하는 이유에 대해 이해할 수 있었다.
만약의 경우에 대해 생각해보자.
공통 기능을 각 구현체마다 동일하게 작성해야할 것이다. 즉 중복 코드가 발생하며 번거롭다.
-> 대신추상클래스
를 쓰자!
이미 a와 b는 각각의 추상 클래스를 상속 중이다. Java에서 클래스는 단 하나의 클래스만 상속 가능하다. 그럼 A와 B에 각각 f 추상메서드를 추가하는 것이 맞을까?
-> 나쁘지 않을지도?
그렇다면 여기서 조건을 추가해보자.
A와 B를 상속하는 다른 클래스(c)가 존재하고 그 클래스는 f 메서드를 가질 수 없다. 이 경우라면?
-> A와 B에 f를 추가하는 것보다 다른 상위클래스
or인터페이스
를 생성하는 것이 좋을 듯하다. 하지만클래스 다중상속
은 불가능. 그렇다면?
->f 추상메서드
를 정의한인터페이스
를 생성하자!
예시를 생각해보니 추상클래스와 인터페이스를 언제 사용해야하는지 감이 오는 듯하다.