[Effective Java] Item20 - 추상 클래스보다는 인터페이스를 우선하라

지구🌍·2023년 2월 25일
0

Effective Java 공부

목록 보기
6/12
post-thumbnail

추상 클래스와 인터페이스

추상 클래스와 인터페이스를 한 번 알아보자!

💡 추상 클래스 : 일부 메소드가 구현되어있지 않고 선언만 되어있는 클래스, 상속을 통해서 클래스를 완성하도록 유도하는 클래스

💡 인터페이스 : 동일한 목적하에 동일한 기능을 수행하게끔 강제하는 구현체

추상클래스인터페이스
공통점객체를 생성할 수 없다.추상 메소드는 하위 클래스에서 구현되어야한다.
차이점일반 메소드와 추상 메소드를 모두 갖을 수 있다.추상 메소드만 가질 수 있다.(default 메소드는 구현이 가능하다.)
멤버 변수를 가질 수 있다.멤버 변수를 가질 수 없다.(static final 변수는 가질 수 있다.)
단일 상속만 가능하다.(동일 클래스를 상속한 클래스들이라면 다중 상속 가능하다.)다중 상속이 가능하다.

인터페이스의 장점

  1. 기존 클래스에도 손쉽게 새로운 인터페이스를 구현해 넣을 수 있다.
    • 인터페이스에 메소드를 추가하고, 클래스 선언에 implements 구문만 추가하면 됨!
  2. 믹스인(mix) 정의에 안성맞춤이다.

    💡 믹스인 : 클래스가 구현할 수 있는 타입으로, 대상 타입의 주된 기능에 선택적 기능을 혼합(mixedin) 한다는 뜻

    • Comparable 대표적 인터페이스
  3. 계층구조가 없는 타입 프레임워크를 만들 수 있다.
  4. 디폴트 메소드를 제공하여 반복되는 코드의 작성을 줄일 수 있다.
    • @impleSpec 자바독 태그르 붙여서 문서화를 꼭 해야함!
    • 공통으로 사용하는 것이기 때문에 주석이나 명세를 통해서 다른 사람에게 꼭 전달되어야함!
  5. 인터페이스와 추상 골격 구현(Skeleton implementation) 클래스를 함께 제공하는 식으로 인터페이스와 추상 클래스의 장점을 모두 취할 수 있다.

골격 구현 작성

  1. 인터페이스에서 다른 메소드들의 구현에 사용되는 기반 메소드를 선정한다.
  2. 위에서 선정한 기반 메소드들을 직접 구현할 수 있는 메소드를 모두 디폴트 메소드로 제공한다.
    • 중복 제거
    • 메소드의 구현이 중복되는 부분을 재정의

인터페이스 -> 골격 구현 클래스 (추상 클래스) -> 구체 클래스

public interface Phone {
    void booting();
    void greeting();
    void shutdown();
    void process();
}
public abstract class AbstractPhone implements Phone {
//Default 메소드
    @Override
    public void booting() {
        System.out.println("booting ...");
    }

    @Override
    public void shutdown() {
        System.out.println("shut down ...");
    }

    @Override
    public void process() {
        booting();
        greeting();
        shutdown();
    }
}
public class Iphone extends AbstractPhone implements Phone {
    @Override
    public void greeting() {
        System.out.println("I am iphone");
    }
}
public class GalaxyPhone extends AbstractPhone implements Phone {
    @Override
    public void greeting() {
        System.out.println("I am galaxy phone");
    }
}
public class Main {
    public static void main(String[] args) {
        Iphone iphone = new Iphone();
        iphone.process();

        GalaxyPhone galaxyPhone = new GalaxyPhone();
        galaxyPhone.process();
    }
}

결론

  • 다중 구현용 타입에는 인터페이스가 적합하다!
  • 복잡한 인터페이스라면 골격 구현을 함께 사용하자!

🎈귀중한 참고자료🎈
참고자료1

profile
일취월장 하며 성장! 중! 공부한 것을 기록하자(^∀^●)ノシ

0개의 댓글