20. 추상 클래스보다는 인터페이스를 우선하라

신명철·2022년 2월 18일
0

Effective Java

목록 보기
18/80

인터페이스의 장점

1. 기존 클래스에도 손쉽게 새로운 인터페이스를 구현해 넣을 수 있다.

기존 클래스에 새로운 인터페이스를 구현하려면 implements 구문으로 추가하고 인터페이스가 제공하는 메서드를 구현하기만 하면 된다.

2. 인터페이스는 믹스인(Mixin) 정의에 안성맞춤이다.

믹스인?
클래스가 구현할 수 있는 타입으로, 믹스인을 구현한 클래스에 원래 주된 타입 외에도 특정 선택적 행위를 제공한다고 선언하는 효과를 준다.

무슨 말인지 모르겠다.
어떤 클래스의 주 기능에 추가적 기능을 혼합한다 해서 믹스인이라고 한다. 그러므로 믹스인 인터페이스는 어떤 클래스의 주 기능 외에 믹스인 인터페이스의 긴으을 추가적으로 제공하게 해주는 효과를 준다.

예를 들어서, Comparable은 자신이 구현한 클래스의 인스턴스들끼리는 순서를 정할 수 있다고 선언하는 믹스인 인터페이스이다. JAVA는 다중 상속이 되지 않기 때문에 추상클래스로는 믹스인을 선언할 수 없다.

3. 인터페이스로는 계층구조가 없는 타입 프레임워크를 만들 수 있다.

타입을 계층적으로 설계하면 수많은 개념을 구조적으로 설명할 수 있지만, 모든 것을 계층적으로 구분할 수 있는 것은 아니다.

public interface Singer {
	AudioClip sing(Song s);
}

public interface Songwriter {
	Song compose(int chartPosition);
}

public interface SingerSongwriter extends Singer, Songwriter {
	AudioClip strum();
	void actSensitive();
}

위 코드는 계층적으로 표현하기 어렵다. 이러한 구조를 클래스로 만들려면 가능한 조합 전부를 각각의 클래스로 정의해야 한다. 즉, 고도비만 계층구조가 만들어지고 이러한 현상을 조합 폭발 현상이라고 부른다.

4. 래퍼 클래스 관용구와 함께 사용하면 인터페이스는 기능을 향상시키는 안전하고 강력한 수단이 된다.

타입을 추상클래스로 정의한다면 그 타입에 기능을 추가하는 방법은 상속 뿐이다. 상속해서 만든 클래스는 래퍼 클래스보다 활용도와 안정성이 떨어진다.

디폴트 메서드

JAVA 8 부터는 인터페이스에서 디폴트 메서드 기능을 제공할 수 있다. 이는 개발자의 수고를 덜어줄 수 있지만 equals 와 hashCode 같은 Object 메서드들은 디폴트 메서드로 제공하면 안된다.

인터페이스와 추상 골격 구현 클래스를 함께 제공하는 방식으로 인터페이스와 추상 클래스의 장점을 모두 취하는 방법도 있다. 인터페이스로는 타입을 정의하고 필요하면 디폴트 메소드 몇 개도 함께 제공한다. 그리고 골격 구현 클래스는 나머지 메소드들까지 구현한다.

public interface Calculator{
	int plus(int x, int y);
    int minus(int x, int y){
    	return x-y;
    }
}
public abstract class AbstractCalculator implements Calculator{
	@override
	public int plus(int x, int y){
    	return x+y;
    }
    
    public abstract int multiply(int x, int y);
}


public CalculatorImpl extends AbstractCalculator implements Calculator{
	
    @Override
    public int multiply(int x, int y){
    	retunr x*y;
    }
}

인터페이스와 구현체 사이에 추상 클래스를 사용해 중복될 수 있는 코드를 제거할 수 있다.

profile
내 머릿속 지우개

0개의 댓글