추상 클래스

클래스를 설계도에 비유한다면 추상 클래스는 미완성 설계도에 비유할 수 있습니다. 추상 클래스는 키워드 abstract를 붙이기만 하면 됩니다.

public abstract class Test {}

추상 클래스는 추상 메소드를 0개 이상 가지고 있다는 것을 제외하고는 일반 클래스와 전혀 다르지 않습니다.

추상 메소드는 간단하게 말하면 선언부는 있는데 구현부가 없는 메소드를 의미합니다.

 

public class 쥐 extends 동물 {
    void 울어보세요() {
        System.out.println("나는 쥐!");
    }
}
public class 고양이 extends 동물 {
    void 울어보세요() {
        System.out.println("나는 고양이!");
    }
}
public class 병아리 extends 동물 {
    void 울어보세요() {
        System.out.println("나는 병아리!");
    }
}
public class 동물 {
    void 울어보세요() {
        System.out.println("동물은 어떻게 울어야 하나요!");
    }
}

동물 클래스 인스턴스는 어떻게 울면 좋을까요? 뭔가 애매하다는 것을 느낄 수 있을텐데요. 이런 경우에 추상 메소드를 사용하면 좋습니다. 메소드의 선언은 있으되 몸체는 없는 형태로 메소드를 구현하는 것입니다.

 

public abstract class 동물 {
    abstract void 울어보세요();
}

이렇게 추상 클래스는 일반 클래스와 크게 다르지 않습니다. 다만 어떤 공통된 클래스들에 대해서 추상화된 부분을 추상 메소드를 통해서 하위 클래스들에게 상속을 통해서 사용할 수 있도록 합니다. IS A~
또한 전혀 다른 클래스들에게 사용한다기 보단 비슷한 특징을 가지고 있는 클래스들에게 사용한다는 특징도 가지고 있습니다.

  • 추상 클래스는 인스턴스, 즉 객체를 만들 수 없는 클래스 입니다.
  • 추상 메소드는 하위 클래스에서 메소드의 구현을 강제해야 합니다.
  • 추상 메소드를 포함하는 클래스는 반드시 추상 클래스여야 합니다.
  • 상속하는 집합간에는 연간관계가 있습니다.
  • 다중 상속이 불가능합니다.

 

추상 클래스의 특징을 요약해서 정리해보면 위와 같이 정리할 수 있을 거 같습니다.



인터페이스

인터페이스는 구현된 것은 아무 것도 없고 밑그림만 그려져 있는 기본 설계도라고 표현할 수 있습니다. 인터페이스는 추상 클래스와 비슷한듯 안비슷한 느낌을 가지고 있는데요. 일단 간략하게 대표적인 특징을 정리하면 아래와 같습니다.

  • 모든 멤버 변수는 public static final 이어야 하며, 이를 생략할 수 있습니다.
  • 모든 메소드는 public abstract 이어야 하며, 이를 생략할 수 있습니다.
  • Java 8 부터는 static, default method를 사용할 수 있습니다.
  • 다중상속이 가능합니다.
  • 상속하는 집합간에는 연관관계가 존재하지 않을 수 있습니다.

 

특징에 대해서는 간략하게 알아보고 이제 본격적으로 인터페이스 vs 추상클래스가 무엇인지 알아보겠습니다.



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

먼저 추상 클래스는 일반 클래스와 크게 다르지 않기 때문에 extends 키워드를 사용하고, 인터페이스는 implements 키워드를 사용해서 상속을 구현하는데요. 왜 이렇게 키워드를 다르게 사용하는 것일까요? 이는 두 개의 차이가 분명히 존재하기에 다르다고 생각하는데요.
먼저 상속에 대해서 알아보겠습니다.

 

상속: 재사용 + 확장

객체지향의 상속은 가족 관계의 상속과는 느낌이 다릅니다. 객체지향의 상속은 재사용과 확장으로 이해하는 것이 더 적절한데요.

대표적으로 위의 그림을 보면 상속 관계가 아닙니다. 객체지향에서의 상속은 상위 클래스의 특성을 하위 클래스에서 상속하고 거기에 더해 필요한 특성을 추가, 즉 확장해서 사용할 수 있다는 의미입니다.

객체지향에서는 상속이란 일반인들이 생각하는 상속이 아닌 확장, 세분화, 슈퍼 클래스 - 서브 클래스 개념으로 이해하는 것이 좋습니다. 그리고 상위 클래스 쪽으로 갈수록 추상화 되었다고 하고, 하위 클래스쪽으로 갈수록 구체화 되었다고 말할 수 있습니다.

또한 상속 관계에서 반드시 만족해야 할 문장이 있습니다.

  • 하위 클래스는 상위 클래스다.

위의 말을 가족 관계에 대입해보겠습니다.

  • 아버지는 할아버지다?
  • 아들은 아버지다?

뭔가 적절하지 않은 것처럼 느껴지는데요. 이번에는 위의 사진 분류도에 대입을 해보겠습니다.

  • 포유류는 동물이다.
  • 고래는 포유류다.
  • 고래는 동물이다.

 

자연스럽게 문장이 이어지는 것을 느낄 수 있을 것입니다. 즉, 상속은 is kind of 관계 입니다.

  • 펭귄 is kind of 동물 -> 펭귄은 동물의 한 분류다.

 

그래서 위의 상속에 대해 정리하면 아래와 같습니다.

  • 객체 지향의 상속은 상위 클래스의 특성을 재사용 하는 것입니다.
  • 객체 지향의 상속은 상위 클래스의 특성을 확장하는 것입니다.
  • 객체 지향의 상속은 is kind of 관계를 만족해야 합니다.

 

이러한 예시를 보면 자바에서 왜 상속 관계에서 다른 키워드가 아닌 extends 키워드를 사용했는지를 알 수 있습니다. 추상 클래스도 상속을 할 때 extends 키워드를 사용하는데요.
즉, 추상 클래스는 이렇게 위에서 말한 상속의 개념처럼 상위 클래스는 하위 클래스에게 특성을 상속해준다는 것을 적용하고 있다는 특징을 가지고 있습니다.

 

하지만 인터페이스는 구현 클래스 is able to 인터페이스 라고 해석할 수 있습니다. 즉, 무엇을 할 수 있는 이라는 표현입니다.

  • Serializable: 직렬화할 수 있는
  • Comparable: 비교할 수 있는
  • Runnable: 실행할 수 있는

 

인터페이스는 클래스가 무엇을 할 수 있다라고 하는 기능을 구현하도록 강제하는 특징을 가지고 있습니다. 그래서 인터페이스는 extends 키워드가 아니라 implements 키워드를 사용하는 것을 알 수 있습니다. 조금 더 깊이 생각하면 아래와 같이도 생각할 수 있습니다.

  • 상위 클래스는 물려줄 특성이 풍성할수록 좋고, 인터페이스는 구현을 강제할 메소드의 개수가 적을수록 좋다는 결론에 도달할 수 있습니다.



정리하기

정리하자면, 인터페이스는 implements 라는 키워드처럼 인터페이스에 정의된 메소드를 각 클래스의 목적에 맞게 기능을 구현하는 느낌이고, 추상 클래스는 extends 키워드를 사용해서 자신의 기능들을 하위 클래스로 확장 시키는 느낌이라고 생각합니다.

추상 클래스, 인터페이스에 대해 하나만 더 예를들어 보면 아래와 같습니다.

  • 추상클래스는 위의 동물 상속 관계에서 하위 클래스들인 고양이, 강아지 등등은 울어보세요() 메소드를 자신 특징에 맞게 확장해서 사용하는 느낌
  • 인터페이스의 대표적으로 JDBC가 있는데 이럴 때는 각 DBMS 들이 자신의 기능에 맞게 인터페이스의 정의된 메소드를 구현한 느낌
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기