면접 준비를 하거나 Spring으로 프로젝트를 개발하면서 추상 클래스나 인터페이스에 대한 개념을 많이 보곤 했다. 하지만 정확히 어떤 것을 의미하는지 제대로 알지 못하고 단순히 암기만 하면서 개념을 이해하려고 노력했다.
김영한님 강의를 들으면서 해당 개념을 더 정확히 알고 오래 기억하고자 글을 남기게 됐다.
인터페이스를 제대로 알기 전에 추상 클래스 개념을 먼저 알아야 한다.
🔍 추상 클래스란?
동물(Animal)은 자식 클래스로 강아지, 고양이, 사자 등을 가질 수 있다.
이때 동물은 추상적인 개념이므로 실제로 직접 인스턴스를 생성해 사용할 일이 없다.
따라서 추상적인 개념을 가진 부모 클래스를 직접 사용하여 활용하는 것을 방지하기 위한 목적으로 추상 클래스를 사용한다.
정확하게는 다음 두 가지 문제를 방지하기 위해 추상 클래스를 사용한다.
- 추상적인 부모 클래스를 직접 생성하는 문제
- 부모 클래스를 상속 받는 곳에서 메서드 오버라이딩을 하지 않는 문제
▶️ 추상 클래스
abstract class AbstractAnimal {...}
- 추상 클래스는 클래스를 선언할 때 앞에 abstract라는 키워드를 붙여주면 된다.
- 추상 클래스는 기존 클래스와 같지만, 추상 클래스로 선언한 클래스의 인스턴스를 직접 생성하지 못한다.
▶️ 추상 메서드
추상 메서드는 부모 클래스를 상속 받는 자식 클래스가 반드시 오버라이딩 해야 하는 메서드를 정의할 수 있게 한다.
실체가 존재하지 않기 때문에 메서드 바디 또한 없다.
public abstract void sound();
- 추상 메서드를 선언할 때 앞에 abstract라는 키워드를 붙여주면 된다.
- 추상 메서드가 하나라도 있는 클래스는 추상 클래스로 선언해야 한다. (abstract class 키워드를 사용해야 한다.)
- 추상 메서드는 상속 받는 자식 클래스가 반드시 오버라이딩 해야 한다.
🔑 인터페이스란?
인터페이스를 본격적으로 설명하기에 앞서 순수 추상 메서드에 대해 알아보자.
▶️ 순수 추상 메서드
순수 추상 클래스는 모든 메서드가 추상 메서드인 추상 클래스를 의미한다.
public abstract class AbstractAnimal {
public abstract void sound();
public abstract void move();
}
순수 추상 클래스는 다음과 같은 특징을 가진다.
- 인스턴스를 생성할 수 없다.
- 상속시 자식은 모든 메서드를 오버라이딩 해야 한다.
- 주로 다형성을 위해 사용된다.
▶️ 인터페이스
인터페이스는 자바에서 제공하는 순수 추상 클래스를 더 편리하게 사용할 수 있는 기능이다.
public abstract class AbstractAnimal {
public abstract void sound();
public abstract void move();
}
위와 같은 순수 추상 클래스 코드를 인터페이스(interface) 키워드를 이용해 다음과 같이 변경할 수 있다.
public interface InterfaceAnimal {
public abstract void sound();
public abstract void move();
}
인터페이스는 순수 추상 클래스에서 편의 기능을 제공한다.
- 인터페이스의 메서드는 모두 public , abstract 이다.
- 메서드에 public, abstract를 생략할 수 있다. 참고로 생략이 권장된다.
- 인터페이스는 다중 구현(다중 상속)을 지원한다.
따라서 아래와 같이 코드를 작성할 수도 있다.
public interface InterfaceAnimal {
void sound();
void move();
}
🌟 다중 구현을 지원하는 인터페이스
자바는 다중 상속을 지원하지 않는다. 그 이유를 잘 모른다면 해당 글을 참고하자.
다중 상속이 불가능한 것과 달리 다중 구현은 가능하다. 그 이유를 알아보자.
먼저, 다중 상속이 안 되는 이유는 다이아몬드 문제가 발생하기 때문이다.
하지만 인터페이스에서는 다이아몬드 문제가 발생하지 않는다.
위 그림과 같이 InterfaceA, InterfaceB는 동일한 메서드인 methodCommon()을 가지고 있다. 그리고 Child를 통해 두 인터페이스를 구현했다. 인터페이스 모두 동일한 이름의 methodCommon()을 제공하지만, 실제 메서드는 Child에서 구현한다.
methodCommon()을 Child에서 오버라이딩하기 때문에 부모를 통해 methodCommon 메서드가 실행되는 것이 아니라 인터페이스를 구현한 Child에서 methodCommon()을 실행한다. 따라서 다이아몬드 문제가 발생하지 않으며, 인터페이스의 경우에는 다중 구현을 허용하는 것이다.
'Java' 카테고리의 다른 글
[JAVA] main() 메서드는 정적 메서드이다! (0) | 2024.07.05 |
---|---|
[JAVA] 자바의 메모리 구조에 대해 알아보자 (0) | 2024.07.03 |
[JAVA] 자바에서 SWAP 구현하기! (1) | 2024.07.03 |
[JAVA] 자바 컴파일과 실행 과정에 대해 알아보자 (0) | 2024.07.02 |
[JAVA] compareTo()에 대해 알아보자(문자열, 숫자 비교) (1) | 2024.04.18 |