본문 바로가기

신입 개발자 면접 기초

JAVA 인터페이스와 추상클래스 공통점, 차이점 정리

반응형

인터페이스(Interface) 와 추상클래스(Abstract class)

- 공통점

: 추상클래스와 인터페이스는 선언만 있고 구현 내용이 없는 클래스다.

(자바8부터 인터페이스에 default method 구현이 가능해졌지만 일반적으로 인터페이스는 구현이 없다.)

따라서 인터페이스와 추상클래스를 가지고 새로운 인스턴스(객체)를 생성할 수 없다.

추상클래스를 extends로 상속받아 구현한 자식클래스나 인터페이스를 implements 하고 구현한 자식클래스만이 객체를 생성할 수 있다.

=> 결국 자식클래스가 무언가 반드시 구현하도록 위임해야할 때 사용해야 한다.


- 차이점

추상클래스

추상클래스는 추상메서드(abstract method)가 하나라도 존재하는 클래스를 말한다.

추상클래스는 추상메서드(abstract method)가 없어도 무방하다.

추상클래스와 인터페이스의 차이점에서 키워드는 목적이다.

추상클래스의 목적은 말 그대로 공통적인 기능을 하는 객체들의 추상화다.

예제들을 보면 사자 클래스, 원숭이 클래스, 고래 클래스 같은 구체적인 클래스가 있고, 추상클래스로 공통기능을 가진 동물 클래스를 만드는 것이 나온다.

이번 포스트에서는 동물 클래스 대신 포유류 클래스를 만들었다고 가정하자.

위키백과에 따르면 포유류는 젖먹이 동물이라고 한다.

즉, 젖을 먹이는 공통적인 기능을 가지고 있고, 각 포유류에 속하는 동물인 사자, 원숭이, 고래에게 중복으로 구현할 필요가 없다.

그래서 추상 클래스인 포유류 클래스를 만드는 것이다.

처음에 말했듯 추상클래스에 "젖을 먹인다" 라는 행위(메서드)를 추상메서드가 없어도 무방하다.

그러면 일반클래스와 뭐가 다른가? 다시 한 번 말하지만 키워드는 "목적"이다.

객체 지향 관점에서 봤을 때 클래스는 어떤 객체를 만드는 틀에 비유한다.

즉, 클래스는 어떤 인스턴스를 생성할 수 있다는 것인데, 추상 클래스는 생성할 수 없다는 특징이 있다. 왜? 추상화된 클래스니까. 형용할 수 없으니까.

포유류 클래스에서 포유류를 생성하면 그 인스턴스(객체)는 뭐라고 구체적으로 말할 수 있을까? 없다. 세상에 없는 객체다.

추상 클래스에 추상 메서드가 없어도 된다는 것에서 일반 클래스와 다른 점을 설명했지만, 인터페이스와 차이점도 일맥상통한다.

추상 클래스는 일반적인 추상화 및 상속에 더 초점을 맞춘다면, 인터페이스는 인터페이스 메서드를 구현하게 하는 것에 초점을 맞춘다고 보면 된다.

포인트는 추상클래스를 언제 사용해야하는 지다.

인터페이스와 추상클래스를 단순하게 자식클래스에서 반드시 구현하게 위임시키는 것만 생각하면 비슷하지만 용도를 봤을 때 다르다.

추상클래스는 말그대로 추상화 시킬 때 사용하면 된다.

책에서 보는 is-a 관계가 핵심이다.

쉽게 말하면 만들어야할 여러 클래스들의 공통점을 찾아 추상화시켜서 사용하는 것이 개발에서 이득일 때!

예를들면 냉장고, TV, 커피머신, 전자렌지등의 클래스를 만들어야할 일이 있을 때 가전제품이라는 추상클래스로 추상화 시켜서 사용하면 좋을 때 사용한다.

가전제품은 공통적으로 (on(), off(), 전기소모(), 기타등) 사용되는 메서드들을 적고, 구체적인 가전제품별로 별도의 동작(메서드)을 나눠서 적는다. 냉장고는 차갑게하고 전자렌지는 물분자운동을 시키는 동작 말이다.

(냉장고 is a 가전제품, 커피머신 is a 가전제품, 전자렌지 is a 가전제품)

상속 받아서 기능을 확장시키는데 목적, 전형적인 상속의 목적

또한 자바특성상 다중상속이 불가한 점을 고려해서 사용해야한다.

요약하면 다중상속 불가, 멤버 변수 존재 가능, 구현된 메서드 존재 가능 이다.


인터페이스

인터페이스는 구현하는 모든 클래스에 대해 특정한 메서드가 반드시 존재하도록 강제하는 역할이다.

구현 객체가 같은 동작을 한다는 것을 보장하기 위한 목적이다.

위의 추상 클래스에서 예제처럼 "젖을 먹인다"라는 행위(메서드)를 사자, 원숭이, 고래 클래스가 한다고 보장하기 위한 목적으로 한다면 인터페이스로 "젖을 먹인다"라는 메서드를 만들어서 해당 객체들이 구현할 수 있다.

판단을 잘해서 써야한다.

또 다른 차이점은 클래스가 아니기 때문에 인터페이스는 다중 상속이 가능하다.

interface도 is-a관계다.

Thread는 runnable이다. 라고 했을 때 인터페이스도 상속이니 is-a관계로 볼 수 있다.

Inheritance (IS-A) vs. Composition (HAS-A) Relationship 으로 상속과 관련되면 is-a로보고 멤버 변수로 사용되면 has-a로 본다. 

* 차이점을 말할 때 다중 상속이 되냐 안되냐는 포인트가 아니다. 목적이 다르다는게 포인트다.


* 참고로 has-a 관계는 어떤 클래스의 멤버 변수로 가지고 있을 수 있으면 뭐든 has-a 관계인 것 같다.

1
2
3
4
5
6
7
8
9
10
11
public class Computer{
    private Cpu cpu;
    private Memory memory;
    //...
    class Cpu{
    //...
    } 
    class Memory{
    //...
    }
}


Computer가 CPU와 Memory를 가지고 있다.

인터페이스를 가지고 있어도 어떤 구성을 나타낸다면 has-a로 볼 수도 있는 것 같다.

반응형
  • 밤둘레 2018.03.29 11:14

    명쾌한 정리 감사합니다!

  • ㄹㅇㄴㄹ 2018.11.05 12:56

    Interface는 IS-A 관계입니다. 저자분께서 올린 글때문에, 저희 학교의 학생분이 틀린답을 작성했습니다. 수정해주시면 감사하겠습니다.
    http://www.cems.uwe.ac.uk/~jsa/UMLJavaShortCourse09/CGOutput/Unit9/unit9(0809)/page_11.htm
    https://en.wikipedia.org/wiki/Is-a

    • Favicon of https://defacto-standard.tistory.com BlogIcon defacto standard 2018.11.08 23:36 신고

      댓글 작성자분 학교의 학생분이 틀린답을 작성한 이유는,

      저자가 내용을 잘못 올려서가 아니라,

      학생이 공부를 제대로 하지 않아서 입니다.

      시험 문제에 나올 정도라면 최소 교재 내지 강의 중에 설명이 있었을 것 같은데요..

      기억이 안날수야 있지만 책에 없는 내용이면 설명을 듣고 필기를 해놓던지 했었어야 하는 부분인 것 같습니다.

      그리고 요즘 대학 교재로 쓰이는 것들 중에선 설명이 없는 것도 찾기 힘들고요.

      수정해야 한다는 것에는 좋은 의견이라 생각하지만, '저자가 잘못 올렸기 때문에' 틀리다니요.

      교재에 해당 내용이 있다면 책보기 귀찮아서, 인터넷에 잘못된 정보가 있을 수도 있다는 사실을 간과하고, 인터넷으로 공부한 학생 탓이죠.

    • 지적 감사드립니다.
      막연히 공부한 것을 공유하면 좋을 것 같아 시작한 블로그 포스팅이었습니다만
      저의 잘못된 지식 공유에 피해를 본 사람이 생기게 되어 죄송하고 안타까운 마음이 듭니다.

  • 추상클래스는 non-static 과 non-final 필드 및 public, private, protected 메소드를 사용 할 수 있다.
    인터페이스는 public, static, final 을 상속할 수 있고 모든 상속 가능한 메소드는 public 이다.
    추상클래스와 인터페이스 언제 사용하나?

    추상클래스
    여러개의 가까운 클래스들 (is-a 관계가 형성될) 사이에 동일한 코드를 공유해서 사용하고 싶을때.
    추상클래스를 상속한 클래스들이 많은 공통 메소드들과 필드와 public 보다 다양한 접근 제어자에 의해 사용하고 싶을때.
    non-static 과 non-final 필드를 선언하고 싶을때. 결과적으로 객체들의 상태를 메소드에서 접근하고 수정 할 수 있게 되겠지.
    인터페이스
    크게 상관없는(is-a 정도는 아닌 has-a 정도인) 클래스들이 너의 인터페이스를 구현( java8 부터는 구현된 것을 사용도 포함)해야 할 필요가 있을때. 예를들어 Comparable and Cloneable
    특정 데이터타입의 행위를 특별하게 구현하길 원할때 그러나 누가 그것의 행위를 구현 했는지에 대한 관심은 없을때
    다중 구현상속의 이점을 누려야 할때


    출처: http://hamait.tistory.com/650?category=79137 [HAMA 블로그]

  • kodw0402 2019.02.26 00:07

    "추상클래스는 추상메서드(abstract method)가 하나라도 존재하는 클래스를 말한다." 라고 하셨는데, 이 부분이 애매모호 하다고 생각합니다.
    제가 배운교재에서는 "굳이 추상클래스는 추상 메소드를 가질 필요는 없다"라고 나와 있습니다:
    "A class that contains abstract methods must be abstract. However, it is possible to define an abstract class that doesn’t contain any abstract methods. In this case, you cannot create instances of the class using the new operator. This class is used as a base class for defining subclasses."
    추상메소드를 하나라도 가진 클래스가 반드시 추상클래스가 되어야한다고 수정해야 할 것 같습니다!

    • 정말 정말 정말 감사합니다!!

      추상클래스 생성하고 추상메서드를 안넣어도 컴파일에 전혀 문제가 없는 것을 확인했습니다.
      상속에도 문제가 없는 것을 확인했습니다.

      다시 한 번 감사드립니다.