추상 클래스
클래스 안에 abstract 메서드가 하나라도 있으면 abstract 클래스로 표기해야 한다. 즉, 추상 메서드를 가진 클래스이다. 그 외에는 일반클래스와 전혀 다르지 않다.
- 생성자, 변수, 메서드 모두 사용 가능 (단, 추상 메서드 1개 이상 필수)
- 추상 메서드는 private일 수 없다. (접근제어자 생략하면 default)
- class A implements 추상클래스 (상속의 개념 is-a)
- 다중상속이 불가능하다.
abstract class 추상클래스 {
int val; // 일반 변수
추상클래스(){} // 생성자
public void 일반메서드(){}
// ...
// 추상 메서드
public abstract void 추상메서드();
(default 생략가능) abstract void 추상메서드2();
}
// A는 추상클래스를 상속했다.
class A extends 추상클래스{
public void 추상메서드(){
// 추상메서드 구현 필수
}
void 추상메서드2(){
// 추상메서드 구현 필수
}
}
인터페이스
인터페이스는 추상 클래스보다 좀 더 유연한 설계도이다. 즉, 더 추상적이라고 보면 된다. 그래서 오직 추상메서드와 상수만 가질 수 있다. java 8부터는 확장성을 위해 디폴트와 static 메서드 사용이 가능해졌다.
- 상수(final), 추상 메서드, 디폴트/static 메서드 사용 가능. 생성자를 가질 수 없다 (인스턴스화 불가)
- 추상 메서드는 public만 가능하다.
- class A implements 인터페이스 (구현 개념 has-a)
- 인터페이스끼리 다중상속이 가능하다.
interface 인터페이스 {
(public static final 생략가능) int 상수이름 = 값;
(public abstract 생략가능) void 추상메서드();
default void 디폴트메서드(){
// 구현
}
}
// A는 인터페이스를 구현헀다.
class A implements 인터페이스 {
void 추상메서드(){
// 추상메서드 구현 필수
}
}
추상 클래스 vs 인터페이스
추상 클래스 | 인터페이스 | |
변수 | 일반 클래스와 동일 | (public staic final) 상수 |
메서드 | 일반 클래스와 동일. 단, abstract 메서드 무조건 1개 이상 |
추상 메서드, 디폴트/static 메서드(jdk 1.8부터) |
메서드 접근제어자 | public, protected, deafult(생략가능) | public만 (생략가능) |
생성자 | o | x |
A {extends / implements} B | extends / 상속 (is-a) | implements / 구현 (has-a) |
A는 B이다 | A는 B를 가지고 있다. | |
다중상속 | 불가능 | 가능 |
추상 클래스는 단일 상속만 가능하고, 인터페이스는 다중상속(구현)이 가능함을 볼 수 있다. 결합력은 추상클래스 > 인터페이스이다.
인용: 자바의 정석
추상 클래스
클래스를 설계도에 비유한다면, 추상클래스는 미완성 설계도에 비유할 수 있다. (완성되지 못한 채 남겨진 설계도) 새로운 클래스가 추상 클래스를 상속받아 추상메서드를 구현해주면 완전한 클래스가 되는 것이다.
- 같은 TV라도 여러 종류의 모델이 있지만, 사실 이들의 설계는 아마 90%정도 동일할 것이다. 그러면 미완성 설계도를 만들어 놓고, 이 미완성 설계도를 이용해서 완성하는 것이 훨씬 효율적이다.
인터페이스
인터페이스는 더 추상화된 설계도로, 구현된 것은 아무것도 없고 밑그림만 그려져 있는 기본 설계도이다. 추상클래스처럼 다른 클래스를 작성하는데 도움을 주는 목적으로 작성하고 다중상속(구현)이 가능하다.
인용: 모던 자바 인 액션 ch18 디폴트 메서드
추상 클래스와 인터페이스는 뭐가 다를까?
자바 8 이후 부터는 인터페이스도 디폴트 메서드가 도입되어 이젠 둘 다 추상 메서드와 바디를 포함하는 메서드를 정의할 수 있다.
추상 클래스 vs 인터페이스
- 인터페이스 다중 구현: 클래스는 하나의 추상 클래스만 상속받을 수 있지만 인터페이스를 여러 개 구현할 수 있다.
- 추상 클래스 인스턴스 변수 공유: 추상 클래스는 인스턴스 변수(필드)로 공통 상태를 가질 수 있다. 하지만 인터페이스는 인스턴스 변수를 가질 수 없다.
인용: effective java item 20
인터페이스와 추상 클래스는 자바가 제공하는 다중 구현 메커니즘이다. 자바 8부터 인터페이스도 디폴트 메서드(default method)를 제공할 수 있게 되어, 이제는 두 메커니즘 모두 인스턴스 메서드를 구현 형태로 제공할 수 있다. 그러면 추상 클래스와 인터페이스와의 차이가 더이상 없는 것일까?
인터페이스와 추상 클래스의 가장 큰 차이는 결합의 정도이다.
- 추상 클래스가 정의한 타입을 구현하는 클래스는 반드시 추상 클래스의 하위 클래스가 되어야 한다는 점이다. 자바는 단일 상속만 지원하니, 추상 클래스 방식은 새로운 타입을 정의하는 데 커다란 제약을 갖는다.
- 인터페이스가 선언한 메서드를 모두 정의하고 그 일반 규약을 잘 지킨 클래스라면 다른 어떤 클래스를 상속했든 같은 타입으로 취급된다.
추상 클래스보다 인터페이스를 우선해야 하는 이유
- 기존 클래스에도 손쉽게 새로운 인터페이스를 구현해 넣을 수 있다. (다중 구현)
- 믹스인(mixin) 정의에 안성맞춤이다. (추상 클래스로는 믹스인을 정의할 수 없다)
- 믹스인이란 클래스가 구현할 수 있는 타입으로, 믹스인을 구현한 클래스에 원래의 ‘주된 타입’ 외에도 특정 선택적 행위를 제공한다고 선언하는 효과를 준다. 예로 Comparable 인터페이스가 있다.
- 이처럼 주된 기능에 선택적 기능을 ‘혼합(mixed in)’한다고 해서 믹스인이라 부른다.
- 계층구조가 없는 타입 프레임워크를 만들 수 있다.
- 래퍼 클래스 관용구(아이템 18)와 함께 사용하면 기능을 향상시키는 안전하고 강력한 수단이 된다.
'Dot Programming > Java' 카테고리의 다른 글
[Java] 자바8에 도입된 인터페이스의 디폴트 메서드 (Default Method) (0) | 2022.02.02 |
---|---|
[Java] 메서드 오버라이딩과 하이딩에 대해 (Overriding and Hiding Methods) (0) | 2022.01.31 |
2022년 자바 개발자 로드맵 (The 2022 Java Programmer RoadMap) (0) | 2022.01.17 |
[Java] 자바가 언제나 Call By Value인 이유 (Call By Reference X) (0) | 2021.09.29 |
[Java] API 호출 및 JSON Parsing 하기 (JSONObject, JSONArray, JSONParser) (0) | 2021.09.22 |