forked from depromeet/effective-java-study
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Item64]: 객체는 인터페이스를 사용해 참조하라 (depromeet#145)(도모)
- Loading branch information
Showing
1 changed file
with
45 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# item64. 객체는 인터페이스를 사용해 참조하라 | ||
|
||
### 서론 | ||
Item51에서 `매개변수 타입으로 클래스가 아니라 인터페이스를 사용하라`고 했다.</br> | ||
이 조언을 `객체는 클래스가 아닌 인터페이스로 참조하라`고까지 확장 할 수 있다.</br> | ||
**적합한 인터페이스만 있다면 매개변수뿐 아니라 반환값, 변수, 필드를 전부 인터페이스 타입으로 선언하라.**</br> | ||
|
||
객체의 실제 클래스를 사용해야 할 상황은 '오직' 생성자로 생성할 때뿐이다. | ||
|
||
### Set 인터페이스를 구현한 LinkedHashSet 변수 선언 예 | ||
```java | ||
/** 좋은 예 - 인터페이스 타입으로 사용 */ | ||
Set<Son> sonSet = new LinkedHashSet<>(); | ||
``` | ||
|
||
```java | ||
/** 나쁜 예 - 클래스 타입으로 사용 */ | ||
LinkendHashSet<Son> sonSet = new LinkedHashSet<>(); | ||
``` | ||
**인터페이스 타입으로 사용하는 습관을 길러두면 프로그램이 훨씬 유연해질 것이다.** | ||
|
||
### 인터페이스 타입의 장점 | ||
- 인터페이스 타입을 사용하면 클라이언트 코드를 수정하지 않고도 참조 객체를 변경할 수 있다. | ||
- 다른 타입의 객체를 사용하더라도 컴파일에러/런타임에러에 대한 걱정을 하지 않아도 된다. | ||
|
||
### 인터페이스 타입의 단점 | ||
- 인터페이스 타입에 선언된 메서드를 구현한 메서드만 사용이 가능하다. | ||
- 특정 구현체의 내부 메서드를 사용할 수 없다. | ||
|
||
### 그럼에도 클래스를 참조해야 하는 경우 | ||
1. 값 타입인 경우 | ||
- String, Integer, Long과 같이 값 타입에 대해서는 인터페이스를 사용할 수 없으니 클래스를 참조해야 한다. | ||
- 또한 Integer, Long과 같은 타입을 사용할 때는 Number와 같은 상위 타입을 사용하지 말아야 한다. </br> | ||
**형변환이 발생 할 때 특정 데이터가 절삭되어 다른 결과가 발생 할 수 있기 때문이다.** | ||
- 이런 경우에는 인터페이스나 상위타입 보다는 본래의 클래스로 참조하는 것이 좋다. | ||
2. 인터페이스에 없는 메서드를 사용 할 경우 | ||
- PriorityQueue 클래스에는 Queue 인터페이스에는 없는 comparator 메서드를 제공한다. | ||
- 클래스 타입을 직접 사용하는 경우에는 추가 메서드를 사용해야 하는 경우로 최소화 하는 것이 좋다. | ||
|
||
### 정리 | ||
- 인터페이스나 추상클래스를 구현하는 클래스를 사용할 때는 참조 변수를 인터페이스나 추상클래스로 사용하자 | ||
- 인터페이스나 추상클래스 타입으로 참조 변수를 사용하면 참조 객체를 바꿔도 안전하다 | ||
- 값 타입을 사용하는 경우에는 클래스 타입의 참조변수를 사용해야 한다. | ||
- 인터페이스에는 없는 메서드를 사용할 때는 클래스 타입의 참조변수를 사용해야 한다. | ||
- 적합한 인터페이스가 없다면 계층구조 중 필요한 기능을 만족하는 가장 덜 구체적인 상위 타입을 사용해야 한다. |