[Java] Interface와 abstract class 차이점과 사용처에 대해서

곰민·2022년 11월 22일
1
post-thumbnail

interface와 abstract class는 java class 설계, 구현 을 하다보면 참 많이 접하게 된다.
유사하지만 다른 차이에 대해서 알아보자.


🚀 Interface


구현에 의존적이다

interface는 특정 기능을 수행하자는 일종의 contract 즉 사전 합의가 주된 목적이기 때문에 interface를 사용하는 의도를 만족시키기 위해서는 implementation 즉 구현에 의존한다.
즉 concrete class로 반드시 구현되어야 하는 일종의 contract인 것.


상태를 가질수 없다

인터페이스는 state 즉 상태를 갖지 못한다.
interface에서의 variable은 전부 static final 이다.
변경 가능한 인스턴스 변수를 사용할 수 없으며 오직 final 변수 즉 변경 가능하지 못한 immutable variable만 사용 가능하다.

public interface levelup {
	int number = 7;
    String name = "개발담곰이";
}
  • 두 변수는 상수이며 인스턴스에 의존적이지 않고 변경될 수가 없다.
    • 값을 변경하려고 한다면 컴파일 에러가 발생한다.

함수형 인터페이스(Java8)

abstract method가 오직 하나뿐인 함수형 인터페이스로 생성이 가능하다.
@functionalInterface 에너테이션으로 함수형 인터페이스 인지 아닌지 체크가 가능하다.

@FunctionalInterface
public interface Supplier<T> {
    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

Default Method

Default Method는 Java8에서 도입되었다.
Default Method는 Abstract Method와는 다르게 Interface 내부에서 구현이 있을 수 있다.
Default Method가 도입되고 "사실 interface는 abstract class와 큰 차이가 없는 것이 아니야?"라고 생각할 수도 있지만.
인터페이스는 state를 가질 수 없기 때문에 사실이 아니다.

public class DefaultMethodExample {

  public static void main(String[] args) {
    Tester tester = new SelfTester();
    challenger.doChallenge();
  }

}

class SelfTester implements Tester { }

interface Tester {

  default void doTest() {
    System.out.println("개발담곰이 test!!");
  }
}
  • 여기서의 포인트는 Default Method들의 인스턴스 생성을 통한 구현이 필요하다는 것.
    Default Method는 static 과같이 사용할 수 없고 static일 수가 없다.

Interface를 사용하는 경우


interface는 decoupling(디커풀링) 즉 모듈, 객체 간 의존성을 낮추고
다형성을 구현하는데 매우 유용하다.

많은 클래스들이 동일한 상위 클래스에 속해 있고 동일한 method action을 갖고 있지만, 다르게 동작하는 경우 interface를 활용하면 매우 좋다.


🚀 Abstract Class


State 즉 상태를 가질 수 있다.

추상 클래스는 인스턴스 변수가 있는 상태를 가질 수 있다.
즉 인스턴스 변수를 사용하고 변경할 수 있음을 의미한다.

public abstract class AbstractClassMutation {

  private String name = "개발담곰이";

  public static void main(String[] args) {
    AbstractClassMutation abstractClassMutation = new AbstractClassImpl();
    abstractClassMutation.name = "변경된 값인 개발담곰이";
    System.out.println(abstractClassMutation.name);
  }

}

class AbstractClassImpl extends AbstractClassMutation { }

// output -> 변경된 값인 개발담곰이

Abstract methods


인터페이스와 마찬가지로 추상 클래스는 추상 메서드를 가질 수 있다.
abstract method 즉 추상 메서드는 method body가 없는 메서드이며
interface와는 다르게 명시적으로 abstract로 선언해야 함.

public abstract class AbstractMethods {

  abstract void dosomething();

}
  • 명시적으로 적지 않으면 컴파일 에러가 발생한다.

추상 클래스를 활용한 좋은 예시

템플릿 메서드 디자인 패턴은 추상클래스를 사용한 것에 대한 좋은 예시.
concrete method 내부에서 인스턴스 변수에 대한 값을 변경하면서 method를 구현하는 방식으로 적용.

*concrete method - abstract class나 interface를 extends or implements 받은 class(concrete class)내부의 구현 method(conrete method)

템플릿 메서드 패턴 바로가기(wiki)

  • 현재 포스팅에서는 Interfaced와 abstract class의 관한 글이므로 템플릿 메서드 패턴에 대해서는 글은 작성하지 않고 링크로 남겨 두겠습니다.

그래서 Interface와 Abstract Class의 주된 차이점은 무엇일까?


  1. OOP 즉 객체지향적 관점에서 본다면 interface와 abstract class의 가장 주된 차이점은
    state 즉 상태 값을 가질 수 있는가 없는가 이다.
  1. interface의 경우 하나 이상을 implement 할 수 있지만 abstract classs는 한 개만 extend가 가능하다.
    예를 들어 물고기 클래스와 사람 클래스를 상속받은 인어 클래스가 있다고 가정해보자.
    인어 클래스에서 숨쉬기라는 기능의 메서드를 호출한다면
    물고기 클래스의 숨쉬기를 가져와야 할까? 사람 클래스의 숨쉬기를 가져와야 할까?
    Diamond Problem이라고 불리는 위와 같은 문제 등의 이유로 자바는 다중 상속을 지원하지 않고 있다.
  1. interface는 클래스로 구현하거나 interface로 확장할 수 있지만 추상 클래스는 extend를 통한 확장만 가능하다.
  1. Lambda는 functional interface에서만 사용할 수 있는 반면 abstract method가 하나만 있는 abstract class는 Lambda를 사용할 수 없다.

표로 보는 차이점


InterfaceAbstract Class
오직 final static 변수만 가능.
interface는 스스로의 상태값을 변경 불가능.
어떤 종류의 인스턴스변수 또는 static 변수를 가질 수 있고
그 변수의 값을 변경시킬 수도 있고
immutable 즉 불변으로 만들어서 사용할 수도 있다.
state를 가질 수 있음.
class는 여러가지의 interface를 implement 할 수 있다.class는 호직 하나의 abstract class만 extend 가능하다
implement 키워드를 사용해서 구현이 가능하다.
interface 끼리는 extends 사용할 수 있다.
extends만 사용 가능.
static fiianl 필드, 파라미터, 또는 메서드의 지역변수만 사용 가능.인스턴스 변수의 가변 필드, 파라미터, 지역 변수등을 가질 수 있다.
funtional interface만 Lambda feature 사용 가능.오직 하나의 abstract method를 갖고있는 abstract class는 lambda를 사용 불가.
생성자를 가질 수 있다.생성자를 가질 수 있다.
abstract method를 가질 수 있다.
default and static methods를 가질 수 있다.
(java8 도입)
private method를 가질 수 있고 implemenation이 가능 하다.
(java9 도입)
어떤 종류의 method든 다 가질 수 있다.

정리

abstract class와 interface는 보는것과 같이 상당부분 다르며,
수정 가능한 상태 즉 가변 상태에 대한 구현이 필요한 경우에는 abstract class를 사용하는 것이 좋고
클래스의 state 즉 상태 값을 유지할 필요가 없는 경우에는 일반적으로 다중상속을 지원하는 interface를 사용하는 것이 좋다.


참조


https://www.infoworld.com/article/2077421/abstract-classes-vs-interfaces-in-java.html
https://stuartmarks.files.wordpress.com/2015/10/con6851-api-design-v2.pdf
https://www.youtube.com/watch?v=o10ETyiNIsM&t=1440s&ab_channel=Java

profile
더 나은 개발자로 성장하기 위해 퀘스트 🧙‍♂🧙‍♂ 깨는 중입니다. 관심사는 back-end와 클라우드입니다.

1개의 댓글

comment-user-thumbnail
2022년 12월 23일

잘봤습니다 멋있는 포스팅이네요^^

답글 달기