[Java/Kotlin] Interface & Abstract class 차이 제대로 이해하기

Jay·2021년 3월 12일
2

Java&Kotlin

목록 보기
21/30
post-thumbnail

우선, 객체지향 설계원칙(SOLID) 중에서 OCP를 생각해보자.

OCP (개방 폐쇄 원칙)

  • 높은 응집도와 낮은 결합도
  • 응집도 : 변화가 알어날 때, 해당 모듈에서 변하는 부분이 큰 정도
  • 결합도 : 하나의 오브젝트가 변경 일어 날 때, 관계를 맺고 있는 다른 오브젝트에게 변화를 요구하는 정도.

확장에 대해 열려 있다.

  • 모듈의 동작을 확장 할 수 있다.
  • 애플리케이션의 요구 사항이 변경 될 때, 이 변경에 맞게 새로운 동작을 추가해 모듈을 확장할 수 있다.
    즉, 모듈이 하는 일을 변경할 수 있다.

수정에 대해 닫혀 있다.

  • 모듈의 소스 코드나 바이너리 코드를 수정하지 않아도 모듈의 기능을 확장하거나 변경할 수 있다.
  • 그 모듈의 실행 가능한 바이너리 형태나 링크 가능한 라이브러리를 건드릴 필요가 없다.

추상 클래스

  • 없거나 하나 이상의 추상 메소드를 가지는 것.
  • 추상 메소드 : 구현되어 있지 않은 abstract로 정의된 메소드.
  1. 클래스 안에 메소드각 한개라도 추상메소드가 있다면 해당 클래스는 반드시 abstract 클래스로 표기 되어야 하며 abstract와 final은 동시 표기 불가하다.

  2. 일반적인 메소드도 있을 수 있고 추상 메소드가 있을 수도 있다.
    추상 클래스도 인터페이스처럼 추상 클래스가 아닌 클래스에서 상속을 받는다면 추상 메소드가 있을 경우 모두 구현해줘야 한다. 물론 추상클래스에서 추상 클래스를 상속 받는다면 모두 구현하지 않아도 된다.

  3. 추상클래스는 생성자를 가질 수 있다.
    추상클래스는 인스턴스를 만들 수 없지만 추상 클래스를 상속받은 클래스를 통하면 인스턴스화가 가능하다.

  4. extens를 사용해서 상속 받으며 추상 클래스의 궁극적인 목적은 상속을 위함이다.


인터페이스

  • body가 비어있는 메소드들의 형태들만 써놓은 것이며 상속하는 클래스들에서 해당 메소드들의 내용을 구현해서 사용해야 하는 메소드들의 집합이다.
  • 개발 코드를 직접 수정하지 않고도 사용하고 있는 객체만 변경할 수 있도록 하기 위함!
  1. 인터페이스에 새로운 메소드를 추가한다고 하고 그 아래에 인터페이스로부터 상속되는 클래스가 있다면 새로운 메소드에 대한 내용을 반드시 구현해야 한다. 인터페이스 안의 모든 메소드들은 추상 메소드이다.

  2. 인터페이스는 final을 붙일 수 없고 인터페이스 변수들은 static이어야 한다.
    즉, 인터페이스는 일반 변수를 가질 수 없다.

  3. 인터페이스는 생성자를 가질 수 없다.
    인터페이스는 인스턴스를 만들 수 없지만 인터페이스를 구현한 클래스를 통해 인스턴스화가 가능하다.

  4. 접근 지정자가 아예 없거나 public 이거나 아님 abstract만 가능하다!
    다른 클래스에선 implements를 통해 구현한다.

  5. 하나 이상의 인터페이스를 상속할 수 있다.


  • 추상 클래스는 객체의 추상적인 상위 개념으로 공통된 개념을 표현할 때 쓴다.
    공통된 속성을 동물이라는 추상 클래스에 추상 메소드로 구현하여 하위 개념인 말이라는 객체에 상속시켜 구현하면 객체의 재사용성과 객체를 표현하는 것이 더 명확해진다.

  • 인터페이스는 구성 요소들이 자주 바뀔 때 쓰면 유용하다!
    메소드 형태만 서로 공유해서 구현(재정의)되는 상황일 때 사용하는 것이 좋다!
    즉, 공통된 메소드(객체 행위)로 만들어 사용하고 싶을 때 인터페이스를 이용하면 효과적이다.

  • 동시 개발이 가능하므로 시간 단축이 많이 된다.
    인터페이스 안의 메소드들은 내용이 없는 상태이나 메소드에 대한 결과값은 내용을 만들지 않아도 미리 알수 있기에 인터페이스의 내용을 누군가가 구현하고 있는 동안 다른 한 사람은 그 메소드가 구현되고 나면 작동할 결과 값으로 같은 시간에 다른 일을 할 수 있기에 개발 작업이 빨라진다.

  • 여러 사람이 인터페이스를 통해 그런 작업을 동시에 한다고 했을 때, 인터페이스 안의 메소드 내용을 변경하더라도 그를 구현한 모든 클래스들을 변경할 필요 없이 해당 메소드의 구현되는 내용만 변경하면 모든 처리가 가능해지는 "높은 응집도와 낮은 결합도"를 해결할 수 있따.


추상 클래스 vs 인터페이스

  • 추상클래스와 인터페이스는 둘 다 인스턴스화 하는 것이 불가하다.
  • 인터페이스는 모든 변수가 기본적은 static final이며 모든 메소드가 public abstract이지만,
    추상 클래스는 static이나 final이 아닌 필드를 지정할 수 있고 public, protected, private 메소드를 가질 수 있다.
  • 인터페이스를 구현하는 어떤 클래스는 다른 여러개의 인터페이스를 다중 구현이 가능하지만
    추상 클래스는 상속을 통해 구현이 가능하기에 다중 상속이 불가하고 그래서 다른 클래스에서 또 상속을 받을 수 없다.

추상 클래스, 인터페이스 적절한 사용 상황

추상 클래스

  • 관련성이 높은 클래스 간 코드 공유할 경우
  • 추상 클래스를 상속받은 클래스들이 공통으로 가지는 메소드와 필드가 많거나 public 이외의 접근제어자(protected, private)가 필요한 경우!
  • non-static, non-final 필드 선언이 필요한 경우
    즉, 각 인스턴스에서 state 변경을 위한 메소드를 선언할 수 있다.

인터페이스

  • 서로 관련성이 없는 클래스들이 인터페이스를 구현하게 되는 경우에 사용한다.
    Ex) Comparable, Cloneable 인터페이스는 여러 클래스들에서 구현 되는데, 구현 클래스들 간 관련성이 없는 경우가 대부분이다!

  • 특정 데이터 타입의 행동을 명시하고 싶은데, 어디서 그 행동이 구현되는지 신경쓰고 싶지 않는 경우!

  • 다중 상속을 허용하고 싶은 경우! (정확히는 다중 구현)

JAVA 8

  • java 8 이전, 둘의 가장 큰 차이는 인터페이스는 메소드 구현부를 가질 수 없지만 추상클래스는 가질 수 있다는 거였다.
    하지만 이젠 default 키워드를 통해 인터페이스도 메소드 구현부를 가질 수 있다.

템플릿 메소드 패턴에서 왜 인터페이스가 아닌 추상클래스를 써야할까?
여기를 보자!

profile
developer

1개의 댓글

comment-user-thumbnail
2022년 6월 23일

좋은 글 감사합니다~

답글 달기