추상 클래스 vs 인터페이스

손효재·2022년 1월 3일
0

Java

목록 보기
4/4

추상클래스 (abstract class)

미완성 클래스로, 하나 이상의 추상 메서드를 포함하는 클래스를 말한다.
추상클래스는 상속을 통해서 자손 클래스에 의해서만 완성될 수 있다.
따라서, 추상 클래스는 동작이 정의되어 있지 않은 추상 메서드를 포함하고 있으므로, 인스턴스를 생성할 수 없다.

추상 메서드 (abstract method)

선언부만 작성하고 구현부는 작성하지 않는 채로 남겨 둔 메서드로, 자식 클래스에서 반드시 오버라이딩해야만 사용할 수 있는 메서드이다.
추상 메서드가 포함된 클래스를 상속받는 자식 클래스가 반드시 추상 메서드를 구현하도록 하기 위한 목적이다.
메서드의 내용이 상속받는 클래스에 따라 달라질 수 있기 때문에 추상 메서드를 사용한다. (다형성을 가지는 메서드의 집합을 정의)

인터페이스 (interface)

다른 클래스를 작성할 때 기본이 되는 틀을 제공하면서, 다른 클래스 사이의 중간 매개 역할까지 담당하는 일종의 추상 클래스를 의미한다.
인터페이스는 동일한 목적 하에 동일한 기능을 수행하도록 강제하여, Java의 다형성을 통해 유지보수성을 높인다.
인터페이스는 클래스에 다중 구현을 지원하고, 인터페이스끼리 다중 상속이 가능하다.
인터페이스는 클래스가 무엇을 할 수 있다라고 하는 기능을 구현하도록 강제하는 특징이다.
ex) Serializable, Comparable, Runnable

Java 8 이전
Java 8 이전에는 상수(public static final), 추상 메서드(public abstract)까지만 선언이 가능했다.

Java 8
default 메서드, static 메서드(클래스 정적 메서드)를 구현할 수 있다.
default 메서드 : 클래스의 인스턴스 메서드와 동일하다. 재정의를 통해 구현 클래스에서 재정의된 인스턴스 메서드로 사용할 수 있다.

Java 8 이후
Java 8에서 인터페이스는 public 정적 멤버만 허용하기 때문에, 별도의 package-private 클래스가 필요할 수 있다. 하지만, Java9 에서는 private 정적 메서드까지 허락하지만, 정적 필드와 정적 멤버 클래스는 여전히 public 이어야 한다.

만약 인터페이스를 구현한다고 하고, 추상 메서드를 구현 클래스에서 실체 메서드를 모두 작성하지 않으면 해당 구현 클래스는 추상 클래스로 선언되어야 한다.
다중 인터페이스를 구현한 구현 클래스는 반드시 모든 인터페이스의 추상 메서드를 실체 메서드로 구현해야 한다.
* 하나라도 추상 메서드가 구현되지 않으면, 구현 클래스는 추상 클래스로 선언되어야 한다.

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

추상 클래스는 is Kind Of , IS - A “~이다” / 인터페이스는 be Able to, HAS - A “~을 할 수 있는”

추상 클래스는 클래스 내에 추상 메서드가 하나 이상이 포함되거나 클래스가 abstract로 정의된 경우를 말한다.
인터페이스는 모든 메서드가 추상 메서드이다. (Java 8에서 default 키워드를 통해 일반 메서드 구현이 가능)

추상 클래스는 extends 키워드를 사용하여 상속하며, 다중 상속은 불가능하다.
반면 인터페이스는 implements 키워드를 사용하여 상속하며, 다중 상속이 가능하다.

추상 클래스는 일반 변수, 생성자, 일반 메서드, 추상 메서드를 모두 가질 수 있는 반면,
인터페이스는 상수와 추상 메서드만 가질 수 있고, 생성자와 일반 변수는 가질 수 없다.

추상 클래스는 extends(상속, 확장의 느낌) 키워드 그대로 자신의 기능들을 하위로 확장시키는 것으로 볼 수 있다.
이를 상속할 각 객체들의 공통점을 찾아 추상화 시켜놓은 것으로,
상속 관계를 타고 올라갔을 때, 같은 부모 클래스를 상속하며, 부모 클래스가 가진 기능들을 구현해야 하는 경우에 사용한다.

인터페이스는 implements(상속, 구현의 느낌) 키워드 처럼 인터페이스에 정의된 메서드를 각 클래스의 목적에 맞게 동일한 기능으로 구현하는 것으로 볼 수 있다.
상속 관계를 타고 올라갔을 때, 다른 부모 클래스를 상속하더라도 같은 기능이 필요한 경우에 사용된다.

ex) 추상클래스 : Creature - Human, Animal / 인터페이스 : Talkable, Flyable, Swimable

인터페이스의 다중상속이 가능한 이유

기존에 Java에서 클래스 다중 상속의 문제점인 동일한 형태의 메서드를 다중 상속했을때, 어떤 클래스의 메서드를 실행해야하는지 판단할 수 없었다.

인터페이스의 메서드는 추상 메서드이기 때문에 메서드명이 겹쳐도 인터페이스를 상속한 클래스에서 해당 메서드를 최종 구현하므로 애매한 부분이 없어 다중상속이 가능하다.

인터페이스도 다중 상속이 안될 수 있다 (feat. default method)

Java8 이상부터 인터페이스에서 메서드 선언시에 default를 명시하여 인터페이스 내부에서 로직이 포함된 메서드를 선언할 수 있다.

하나라도 추상 메서드로 되어있다면, 재정의 하여 사용할 수 있지만, 동일한 메서드명의 메서드들이 default 메서드로 정의 되어있다면 인터페이스에서도 다중 상속을 지원하지 않기 때문에, 중복되는 default 메서드를 무조건 오버라이딩 해주어야한다.

인터페이스에서 default 메서드 구현 가능이 추가된 이유

default 메서드의 추가 이유는 “하위 호환성”이다.

ex) 자동차에 비행이라는 기능이 추가되면, 원래의 인터페이스에 추가하게 되면 해당 인터페이스를 구현한 구현체를 모두 다시 작성해야 한다.

기존에 존재하던 인터페이스를 이용해 구현된 클래스들을 사용하고 있는데, 인터페이스를 보완하는 과정에서 추가로 구현해야할 필수적인 메서드가 생긴다면, 이미 이 인터페이스를 구현한 클래스와는 호환성이 떨어지게 된다.

따라서 default 메서드를 추가하여 필수적으로 구현해야할 메서드를 정의하면 하위 호환성이 유지되며 인터페이스를 보완할 수 있다.

0개의 댓글