본문 바로가기

신입 개발자 면접 기초

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로 볼 수도 있는 것 같다.

반응형