201222 추상 클래스와 인터페이스

2020-12-22

추상 클래스와 인터페이스

‘이펙티브 자바’ item 20~22를 읽고,

추상 클래스와 인터페이스의 정의와 둘 사이의 공통점/차이점에 대해 한번 더 복습하는 시간을 가지려고 합니다!

추상 클래스

public abstract class Cat{
    public void meow(){
        System.out.println("애옹");
    }
    public abstract void jump();
}

// 추상 클래스는 상속하여 사용한다
public class MomCat extends Cat{
 	@Override
    public void jump(){
        System.out.println("책상 위로 점프합니다");
    }
}
public class Kitten extends Cat{
 	@Override
    public void jump(){
        System.out.println("아기 고양이는 점프할 수 없어요");
    }
}
  • 메서드를 선언하기는 하지만 모든 메서드를 정의하지는 않는, 불완전하게 정의된 클래스
  • 불완전하게 정의되어 있기 때문에 추상 클래스의 인스턴스는 만들 수 없다.
  • static이나 final이 아닌 필드를 지정할 수 있다
  • public, protected, private 메서드를 가질 수 있다
  • 이것을 베이스 클래스로 상속해서 더 구체적인 클래스를 만들어서 사용하는 경우 사용하기 좋다.
    • 공통으로 가지는 메소드와 필드가 많은 경우
    • static 또는 final이 아닌 필드가 필요한 경우
    • 접근제어자 사용이 필요한 경우
  • 서브 클래스에서 써먹을 수 있는 공통적인 기능을 추상 베이스 클래스에 집어넣는다.

인터페이스

public interface Flyable{
    public void fly();
}
// 인터페이스는 '구현한다'
public class Airplane implements Flyable{
    @Override
    public void fly(){
        System.out.println("비행기가 날아갑니다");
    }
}
public class Bird implements Flyable{
    @Override
    public void fly(){
        System.out.println("새가 날아갑니다");
    }
}
  • 클래스와 별도로 일련의 연관된 메서드를 선언한다.
  • 자바 8부터 default 예약어를 이용하여 일반 메서드 구현이 가능하다
  • 인터페이스는 static final 필드만 가질 수 있다
    • 필드를 선언할 때는 public static final이 생략되어 있다고 생각하자
    • public static final의 목적
      • 구현 객체의 같은 동작을 보장하기 위한 목적
      • 인터페이스의 변수는 스스로 초기화될 권한이 없다
        • 아무 인스턴스도 존재하지 않는 시점이기 때문
  • 클래스 계층구조와는 독립적으로 애플리케이션 프로그래밍 인터페이스(Application Programming Interface, API)를 정의하는 것과 같은 역할을 하게 된다.
  • 인터페이스는 인스턴스를 만들 수 없다.
  • 데이터 멤버 및 메서드 정의가 들어있지 않은 추상 클래스와 거의 유사하다(실제 C++에서는 이런 식으로 인터페이스를 정의한다)
  • 서로 관련이 없는 클래스에서 개념적으로 연관된 기능을 작동시킬 수 있는 공통된 방식이 필요하지만, 그 기능을 구현하는 방법은 제각기 다른 경우 인터페이스를 사용한다.

추상 클래스와 인터페이스의 공통점과 차이점

공통점

  • 선언만 있고 구현 내용은 일부만 있거나 없다
    • 다른 클래스에서 구현 내용을 완성하는 것을 강제한다
  • 인스턴스화 할 수 없다(new연산자를 이용해 객체를 생성할 수 없다)

차이점

  • 추상클래스는 is-a 관계에서 사용 / 인터페이스는 has-a 관계에서 사용
    • 추상 클래스의 목적은 상속을 받아 기능을 확장시키는 것이다
    • 인터페이스의 목적은 서로 관련이 없는 클래스에서 개념적으로 연관된 기능을 작동시킬 수 있는 메서드가 반드시 존재하도록 강제하는 역할이다

출처

Do it! 자바 프로그래밍

프로그래밍 면접 이렇게 준비한다